其他分享
首页 > 其他分享> > 【浅谈数据结构】队列的基本函数与操作

【浅谈数据结构】队列的基本函数与操作

作者:互联网

文章目录

1、定义及基本运算

定义:

队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表

说明:

  (1)、允许删除的一端称为队头(Front)
  (2)、允许插入的一端称为队尾(Rear)
  (3)、当队列中没有元素时称为空队列
  (4)、队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表

注意:

队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。
  【例】在队列中依次加入元素a1,a2,…,an之后,a1是队头元素,an是队尾元素。退出队列的次序只能是a1,a2,…,an。

2、队列的基本运算

(0)、队列的定义


typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QueueNode;

//在这里使用了一个结构体对于 head tail 进行封装,便于后续使用
typedef struct Queue
{
	QueueNode* head;//头指针,队非空时指向队头元素
	QueueNode* tail;//尾指针,队非空时指向队尾元素的下一位置 
	
}Queue;

(1)、QueueInit(Q)

置空队。构造一个空队列Q。

(2)、QueueEmpty(Q)

判队空。若队列Q为空,则返回真值,否则返回假值。

(3)、 QueueFull(Q)

判队满。若队列Q为满,则返回真值,否则返回假值。

注意:
 此操作只适用于队列的顺序存储结构。

(4)、EnQueue(Q,x)

若队列Q非满,则将元素x插入Q的队尾。此操作简称入队。

(5)、 DeQueue(Q)

若队列Q非空,则删去Q的队头元素,并返回该元素。此操作简称出队。

(6)、QueueFront(Q)

若队列Q非空,则返回队头元素,但不改变队列Q的状态。

一、顺序队列

(1)、顺序队列的定义

队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。

(2)、 顺序队列的表示

  ① 和顺序表一样,顺序队列用一个向量空间来存放当前队列中的元素。
  ② 由于队列的队头和队尾的位置是变化的,设置两个指针front和rear分别指示队头元素和队尾元素在向量空间中的位置,它们的初值在队列初始化时均应置为0。

(3)、 顺序队列的基本操作

  ① 入队时:将新元素插入rear所指的位置,然后将rear加1。
  ② 出队时:删去front所指的元素,然后将front加1并返回被删元素。

注意:

  ① 当头尾指针相等时,队列为空。
  ② 在非空队列里,队头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。

二、循环队列

在这里插入图片描述

顾名思义,就是充分利用一段内存空间的队列


typedef Sturet{              
      int front;               //头指针,队非空时指向队头元素
      int rear;               //计数器,记录队中元素总数
      DataType cnt[QueueSize]//计数器,记录队中元素总数
}CirQueue;//循环队列的别名

循环队列的基本运算

① 置队空

void InitQueue(CirQueue *Q)
{
        Q->front=Q->rear=0;
        Q->count=0;     //计数器置0
 }

② 判队空

int QueueEmpty(CirQueue *Q)
{
     return Q->count==0;  //队列无元素为空
 }

③ 判队满

int QueueFull(CirQueue *Q)
    {
        return Q->count==QueueSize;  //队中元素个数等于QueueSize时队满
     } 

④ 入队

void EnQueue(CirQueuq *Q,DataType x)
 {
    if(QueueFull((Q))                  
           Error("Queue overflow");     //队满上溢
    Q->count ++;                        //队列元素个数加1
    Q->data[Q->rear]=x;                 //新元素插入队尾
    Q->rear=(Q->rear+1)%QueueSize;      //循环意义下将尾指针加1

⑤ 出队g

DataType DeQueue(CirQueue *Q)
  {
      DataType temp;
      if(QueueEmpty((Q))
           Error("Queue underflow");     //队空下溢
      temp=Q->data[Q->front];
      Q->count--;                        //队列元素个数减1
      Q->front=(Q->front+1)&QueueSize;   //循环意义下的头指针加1
      return temp;
   }     
 

三、链队列

队列的链式存储结构简称为链队列。它是限制仅在表头删除和表尾插入的单链表。(不一定非要使用单链表)

和链栈类似,无须考虑判队满的运算及上溢。

基本运算

①、置空队

void InitQueue(LinkQueue *Q)
{
      Q->front=Q->rear=NULL;
}

②、判队空

intQueueEmpty(LinkQueue *Q)
{
      return Q->front==NULL&&Q->rear==Null;
      //实际上只须判断队头指针是否为空即可
}

③、入队

void EnQueue(LinkQueue *Q,DataType x)
{//将元素x插入链队列尾部
      QueueNode *p=(QueueNode *)malloc(sizeof(QueueNode));//申请新结点
      p->data=x;   p->next=NULL;
      if(QueueEmpty(Q))
          Q->front=Q->rear=p;  //将x插入空队列
      else { //x插入非空队列的尾
          Q->rear->next=p;     //*p链到原队尾结点后
          Q->rear=p;           //队尾指针指向新的尾
       }
 }

④、出队

DataType DeQueue (LinkQueue *Q)
{
       DataType x;
       QueueNode *p;
       if(QueueEmpty(Q))
            Error("Queue underflow");//下溢
       p=Q->front;                   //指向对头结点
       x=p->data;                    //保存对头结点的数据
       Q->front=p->next;             //将对头结点从链上摘下
       if(Q->rear==p)//原队中只有一个结点,删去后队列变空,此时队头指针已为空
            Q->rear=NULL;
       free(p);   //释放被删队头结点
       return x;  //返回原队头数据
 }

⑤、取队头元素

DataType QueueFront(LinkQueue *Q)
{
      if(QueueEmpty(Q))
           Error("Queue if empty.");
       return Q->front->data;
 }

标签:队头,浅谈,队列,元素,front,数据结构,rear,指针
来源: https://blog.csdn.net/GuLeng______/article/details/122735424