> 文档中心 > 开卷数据结构(6)—— 队列 一学就会,一用就废

开卷数据结构(6)—— 队列 一学就会,一用就废


💟作者简介:大家好,我是Ceylan_,可以叫我CC ❣️    
📝个人主页:Ceylan_的博客
🏆博主信息:平凡的大一学生,有着不平凡的梦

         专栏  

  • 备战蓝桥杯   
  • 力扣每日一题
  • 开卷数据结构

⚡希望大家多多支持😘一起进步~❤️
🌈若有帮助,还请关注点赞收藏,不行的话我再努努力💪

目录

🌺队列的定义 

🌺队列的顺序表达与实现

🌷队列顺序存储结构

🌷假溢出

🌷循环队列

🌹循环队列的初始化

🌹循环队列的入队

🌹循环队列的出队

🌷链队列

🌹链栈的初始化

🌹链栈的入队

🌹链栈的出队

🌺每日金句


🌺队列的定义 

队列是一种线性表,但限定这种线性表只能在表的一端进行插入,在另一端进行删除

 ⚠️对头:允许删除的一端,又称为队首

 ⚠️队尾:允许插入的一端


 

队列与生活中的排队一样,最早排队的最先离开。

由此可见:队列的操作特性可以明显地概括为先进先出

队列有两种存储表示,顺序表示链式表示

🌺队列的顺序表达与实现

🌷队列顺序存储结构

和顺序栈相类似,在队列的顺序存储结构中,除了用一组地址连续的存储单元依次列头到队列尾的元素之外,尚需附设两个整型变量【front】和【rear】分别指示队列头元素及队间的位置(后面分别称为头指针和尾指针)。

队列的顺序存储结构表示如下:

#define   MAXSIZE    100//队列容量typedef   struct {   ElemType *base;      //存储空间int front,rear;     //队首,队尾}SqQueue ;

🌷假溢出

图(1)所示为队列的初始状况,此时有【front == rear == 0成立。该条件可以作为队列判空的条件。但是【rear == MAXSIZE】不能作为队列满的条件。如 图(4),队列中只有一个元素,仍满足该条件。这时入队出现上溢出,但是这种溢出并不是真正的溢出,在队列中依然存在可以存放元素的空位置,所以是一种假溢出

如何解决循环链表的这一缺点呢?

🌷循环队列

将顺序队列臆造成一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列

🌹循环队列的初始化

循环队列的初始化就是动态分配一个预定义大小为 MAXSIZE 的数组空间

🔺实现原理

1️⃣为队列动态分配一个最大容量为MAXSIZE的数组空间

2️⃣base指向数组空间的首地址

3️⃣头指针与尾指针置为零,表示队列为空

💬 代码演示

Status InitQueue ( SqQueue  &Q ){Q.base=new  ElemType[MAXSIZE];if(!Q.base)return OVERFLOW;Q.front=Q.rear=0;return OK;} 

🌹循环队列的入队

入队操作是指在队尾插入一个新的元素

🔺实现原理

1️⃣判断队列是否满

2️⃣满了返回ERROR

3️⃣将新元素插入队尾

4️⃣队尾指针加一

💬 代码演示 

Status EnQueue(SqQueue &Q,ElemType e){    if((Q.rear+1)%MAXSIZE==Q.front)//判满    return ERROR;Q.base[Q.rear]=e;Q.rear=(Q.rear+1)%MAXSIZE;return OK;}

🌹循环队列的出队

出队操作是删除队头元素

🔺实现原理

1️⃣判断队列是否为空

2️⃣为空返回ERROR

3️⃣保留队头元素

4️⃣队头指针加一

💬 代码演示 

Status DeQueue(SqQueue &Q, ElemType &e){    if( Q.rear==Q.front ) return ERROR;//判空e = Q.base[Q.front];Q.front = (Q.front+1)%MAXSIZE;return OK;}

🌷链队列

队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表,头指针指向对头结点,尾指针指向队尾结点。

队列的链式存储如图:

队列的链式存储类型可描述为:

typedef struct Qnode{ElemType data;    struct QNode * next;}Qnode,*QueuePtr;    //结点typedef struct { QueuePtr  front;QueuePtr rear;}LinkQueue;  //链队  

🌹链栈的初始化

链栈的初始化操作就是构建一个只有头结点的空队。

🔺实现原理

1️⃣生成新结点作为头结点

2️⃣队头指针和队尾指针指向该结点

3️⃣头指针的指针域置空

💬 代码演示 

Status InitQueue(LinkQueue &Q){Q.front=Q.rear=new QNode;p->next=NULL;return OK;} 

🌹链栈的入队

🔺实现原理

1️⃣为入队元素分配结点空间,用指针p指向

2️⃣将新结点数据域置为e

3️⃣将新结点插入到队尾

4️⃣修改队尾指针为p

💬 代码演示 

Status EnQueue(LinkQueue &Q,ElemType e){p=new QNode;//为入队元素分配结点空间,用指针p指向p->data=e; //将新结点数据域置为ep->next=NULL;Q.rear->next=p;     //将新结点插入到队尾Q.rear=p;//修改队尾指针为preturn OK;}

🌹链栈的出队

🔺实现原理

1️⃣判断是否为空,为空返回ERROR

2️⃣保留头元素空间,以备释放

3️⃣修改头指针的指针域,指向下一结点

4️⃣判断出队元素是否是最后一个元素,若是,将队尾指针重新赋值,指向头结点

5️⃣释放原队头元素的空间

💬 代码演示 

Status DeQueue(LinkQueue &Q,ElemType &e){if(Q.front==Q.rear)//若队列为空,返回ERRORreturn ERROR;QNode *p=Q.front->next;//保留头元素空间,以备释放Q.front->next=p->next;//修改头指针的指针域,指向下一结点    if(Q.rear==p)//判断出队元素是否是最后一个元素,若是,将队尾指针重新赋值,指向头结点Q.rear=Q.front; delete p;//释放原队头元素的空间return OK;}

🌺每日金句

最困难的时候,也就是离成功不远的时候。——拿破仑

     本人不才,如有错误,欢迎各位大佬在评论区指正。有帮助的话还请【关注点赞收藏】,不行的话我再努努力💪💪💪