数据结构:队列及其应用

(一)什么是队列?

队列也是一种线性表,它只允许在表的一端进行插入操作,而在表的另一端进行删除操作。

  1. 队头(Front):只允许删除的一端,又称队首;
  2. 队尾(Rear):只允许插入的一端;

(二)队列的应用有哪些?

  1. 当我们需要顺序处理一组数据,但数据量在不断变化时可以使用队列来解题;
  2. 广泛应用于广度优先遍历中,比如当我们需要层次遍历二叉树的各个节点,就可以借助队列来实现。

(三)队列的存储结构有哪些?

(1)顺序存储

分配一块连续的存储单元存放队列中的元素

#define MaxSize 50 //定义队列中元素的最大个数
typedef struct{
	ElemType data[MaxSize];//存放队列元素
	int front,rear;//对头指针和队尾指针
}SqQueue
顺序存储有什么缺点?

不能用Q.rear== MaxSize 作为队满条件,因为当我们删除队列中的一个元素时会出现“假溢出”现象,即rear指针指向队尾,但data数组中依然存在可以存放元素的空位置。

(2)循环队列

① 什么是循环队列?

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

循环队列可以解决“假溢出”问题。

循环队列中,当队首指针Q.front=MaxSize-1后,再前进一个位置就自动到队列下标为0的位置。(可以用取余运算来实现)

  1. 初始时:Q.front=Q.rear=0
  2. 队首指针进1:Q.front=(Q.front+1)%MaxSize
  3. 队尾指针进1:Q.rear=(Q.rear+1)%MaxSize
  4. 队列长度:(Q.rear+MaxSize-Q.front)%MaxSize

② 循环队列中队空队满的判断条件是什么?

方法一:牺牲一个存储单元

约定以“队头指针在队尾指针的下一位置作为队满的标志”

![[Pasted image 20221019192932.png|200]]

  1. 队满条件:(Q.rear+1)%MaxSize == Q.front
  2. 队空条件:Q.front == Q.rear
  3. 队列中元素的个数:(Q.rear-Q.front+MaxSize)%MaxSize
方法二:在队列类型中增设表示元素个数的数据成员
  1. 队满条件:Q.size == MaxSize
  2. 队空条件:Q.size == 0
  3. 队列中元素的个数:size
方法三:在队列类型中增设tag数据成员

约定删除元素设置tag=0、插入元素设置tag=1

  1. 队满条件:tag=1,插入导致Q.front == Q.rear
  2. 队空条件:tag=0,删除导致Q.front == Q.rear

④ 循环队列有哪些基本操作?

(1)初始化
void InitQueue(SqQueue &Q){
	Q.rear=Q.front;
}
(2)判队空
bool isEmpty(SqQueue Q){
	if(Q.rear=Q.front) return true;
	else return false;
}
(3)入队
bool EnQueue(SqQueue &Q,ElemType x){
	if((Q.rear+1)%MaxSize==Q.front) return false;
	Q.data[Q.rear]=x;
	Q.rear=(Q.rear+!)%MaxSize;
	return true;
}
(4)出队
bool DeQueue(SqQueue &Q,ElemType &x){
	if(Q.rear==Q.front) return false;
	x=Q.data[Q.front];
	Q.front=(Q.front+1)%MaxSize;
	return true;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值