数据结构队列介绍

队列的定义

队列是一种操作受限的线性表 ,只允许在表的前端(front)进行删除操作又称作出队,在表的后端进行插入操作,称为入队,符合先进先出(First in First out)的特性。在队尾插入元素叫做入队,对头删除元素叫做出队。

队列实现方式

队列有顺序队列链式队列,两者的区别仅是顺序表和链表的区别,即在实际的物理空间中,数据集中存储的队列是顺序队列,分散存储的队列是链队列。

顺序队列(基于数组实现)

可以看到,要实现一个顺序队列,我们需要以下结构:

  1. 存储数据的数组 ——`data[]`
  2. 表示队列的最大容量的值 ——`MAXSIZE`
  3. 标识队头端的队头下标——`front`
  4. 标识队尾端的队尾下标 ——`rear`
#define MAXSIZE 5 //顺序队列的最大存储容量
/*顺序队列的结构体*/
typedef struct {
    int data[MAXSIZE];
    int front; //队头下标
    int rear; //队尾下标
} QueueArray;

 front rear 会随着入队和出队操作而变化,当元素入队时,rear加一,当元素出队时 front+1。为了方便起见,我们规定在非空队列中,队尾下标是队尾元素的下一个元素的下标 。

注意:

假溢出:指队列进行多次入队与出队操作之后,队尾指针已经指向数组最后一个位置,但队列并没有被填满,如果再插入新的元素,就会超过数组的长度,这种溢出我们称为假溢出。

真溢出:指队列进行多次入队与出队操作之后,队尾指针已经指向数组最后一个位置,并且此时队列已经被填满,如果再插入新的元素,就会超过数组的长度,这种溢出我们称为真溢出。

 链式队列(基于链表实现)

 

可以看到,要实现一个链队列,需要以下结构:

1)单链表的基本单元结点 ——`QueueNode`
   1.1)存储数据的数据域 ——`data`
   1.2)指向下一个结点的指针域 ——`next`
2)指向链表的头指针 ——`head`
3)标识队头端的队头指针 ——`front`
4)标识队尾端的队尾指针 ——`rear`

/*单链表的结点的结构体*/
typedef struct QueueNode {
    int data; //数据域
    struct QueueNode *next; //指针域
} QueueNode;

/*链队列的结构体*/
typedef struct {
    QueueNode *front; //队头指针
    QueueNode *rear; //队尾指针
} QueueLink;

 

其中,头指针 head 和队头指针 front都指向了单链表的第一个结点,所以这个指针可以合二为一,队头指针即头指针。

如此一来,我们可以借助链表的尾插法实现队列的入队操作,借助链表的头删法实现队列的出队操作。

循环队列

元素进行多次入队出队后,用于实现队列结构的开头部分的数组的开头部分空间会浪费,并且为了克服“假溢出”的情况可以将顺序队列优化成循环队列。循环队列是把顺序队列首位相连,在逻辑上把它看成一个环。

入队:队尾循环后移, rear =(rear+1)%Maxsize;
出队:队首循环后移, front =(front+1)%Maxsize;
队空:front=rear; // rear 和 front 指向同一个位置
队满:(rear+1) %Maxsize=front; // rear 向后移一位正好是 front

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值