数据结构之队列

目录

一、队列的基本概念

二、队列的顺序实现

        1、队列的顺序存储

        2、队列的初始化 

        3、入队操作 

        4、出队操作

        5、其他方法 

三、队列的链式存储 

        1、队列的链式存储

        2、链队列的初始化 

        3、入队操作 

        4、出队操作 

四、双端队列


一、队列的基本概念

        队列简称队,也是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队,删除元素称为出队或离队,其操作特性是先进先出。

        队头:允许删除的一端

        队尾:允许插入的一端

        空队列:不含任何元素的空表

二、队列的顺序实现

        1、队列的顺序存储

        队列的顺序实现是指分配一块连续的存储单元存放队列中的元素,并附设两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置(不同的指针定义操作会有所不同),队列的顺序存储类型可以描述为

#define MaxSize 50            //定义队列中元素的最大个数
typedef struct{
	ElemType data[MaxSize];    //用数组存放队列元素
	int front,rear;            //队头指针和队尾指针
}SqQueue;

        2、队列的初始化 

        对队列进行初始化时,队头队尾指针均指向0,判断队列是否为空的条件是队头队尾指针指向相同位置。

        3、入队操作 

        队不满时,先送值到队尾元素,再将队尾指针加1,但能否用Q.rear==MaxSize作为队列满的条件呢?显然不能,当队列元素占满空间,此时进行出队操作,如下图所示,队列中变为7个元素,仍满足Q.rear==MaxSize。这时入队出现“上溢出”,但这种溢出不是真正的溢出,在data数组中依然存在可以存放元素的空位置,所以是一种“假溢出”。

         循环队列

        对于“假溢出”的问题,这里引入循环队列的概念,将顺序队列臆造为一个环状的空间,即把存储队列元素的表从逻辑上视为一个环,称为循环队列。

        4、出队操作

特定条件下循环队列队头/队尾指针的初值

初始时:Q.front=Q.rear=0

队首指针进1:Q.front=(Q.front+1)%MaxSize

队尾指针进1:Q.rear=(Q.rear+1)%MaxSize

队列长度:(Q.rear+MaxSize-Q.front)%MaxSize

出队入队时:指针都按顺时针方向进1

         循环队列队空、队满的判断条件

        1)牺牲一个单元来区分队空和队满,入队时少用一个队列单元,约定以“队头指针在队尾指针的下一个位置作为队满的标志”。

        队满条件:(Q.rear+1)%MaxSize==Q.front

        队空条件:Q.front==Q.rear

        队列中元素的个数:(Q.rear-Q.front+MaxSize)%MaxSize

        2)类型中增加size数据成员,表示元素个数。删除成功size-1,插入成功size+1。队空时Q.size==0;队满时Q.size==MaxSize,两种情况都有Q.front==Q.rear。

        3)类型中增加tag数据成员,以区分队满还是队空。删除成功置tag=0,若导致Q.front==Q.rear,则为队空;插入成功置tag=1,若导致Q.front==Q.rear,则为队满。

        5、其他方法 

        如果队尾指针指向的不是队尾元素的下一个位置,而是队尾元素,则需要先将队尾指针加1,然后再入队。

        初始化设置rear=MaxSize-1,入队时先使rear+1,然后将元素插入到rear=0的位置上,判空的条件为(Q.rear+1)%MaxSize==Q.front,而判满的条件有多种选择,方案一是牺牲一个存储单元,此时(Q.rear+2)%MaxSize==Q.front;方案二则是设置size或tag变量进行判断。

三、队列的链式存储 

        1、队列的链式存储

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

        2、链队列的初始化 

        对于带头结点的链队列,首先申请一个头结点并让front和rear同时指向头结点,然后使头结点的next指针指向NULL。通过front指针和rear指针是否指向同一个结点判断队列是否为空,也可以通过头结点的next指向是否为空即Q.front->next=NULL来判断队列是否为空。

        对于不带头结点的链队列,只需让头指针和尾指针都指向NULL即可,判断队列是否为空也通过头指针或尾指针是否指向NULL来判断。

        3、入队操作 

        4、出队操作 

 

        不难看出,不带头结点的链式队列在操作中往往比较麻烦,因此通常将链式队列设计成一个带头结点的单链表。链式存储一般不会队满,除非内存不足。

四、双端队列

        双端队列是指允许两端都可以进行插入和删除操作的线性表,两端地位是平等的,为了方便理解,将左端也视为前端,右端也视为后端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值