数据结构之队列

本文详细介绍了数据结构中的队列,包括其基本概念和性质,如先进先出原则。讨论了顺序队列和链式队列的实现,特别提到了循环队列解决队满问题的方法。此外,还介绍了链式队列的特点,以及双端队列的操作。这些内容对于理解和应用队列数据结构至关重要。
摘要由CSDN通过智能技术生成

基本概念和性质

  • 先进先出:最后插入队列中的元素总是最后被删除;每次从队列中删除的总是最早插入的元素

  • 栈和队列的主要区别:插入、删除操作的限定不一样

顺序队列

顺序队列会产生“假溢出”的问题,即无法使用 Q.rear == Q.front 来区分队空和队满,因此引入循环队列

  • 判断队空队满
    1. 牺牲一个单元来判断
      1. 队满:(Q.rear + 1) % MaxSize == Q,front
      2. 队空: Q.rear == Q.front
      3. 队中元素的个数:(Q.rear - Q.front + MaxSize) % MaxSize
    2. 设置计数器
      1. 队满:Q.size == MaxSize
      2. 队空:Q.size == 0
      3. 队中元素的个数:Q.size
    3. 设置判断标志
      1. 队满:Q.flag == 0时,若执行入队操作导致 Q.rear == Q.front 则为队空
      2. 队空:Q.flag ==1时,若执行出队操作导致 Q.rear == Q.front 则为队空
// 创建队列结构
#define MaxSize 10

typedef struct {
	ElemType data[MaxSize]; // 数据
	int front, rear; // 队头、队尾
} SqQueue;
// 初始化队列
void InitQueue(SqQueue &Q){
	Q.front = 0;
	Q.rear = 0;
}
// 队列判空
bool isEmpty(SqQueue Q) {
	if(Q.front == Q.rear) 
		return true;
	else 
		return false;
}
// 入队
bool EnQueue(SqQueue &Q, ElemType x) {
	if((Q.rear + 1) % MaxSize == Q.front)	// 队满
		return false; 
	Q.data[Q.rear] = x;
	Q.rear = (Q.rear + 1) % MaxSize;
	return true;
// 出队
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;
}
// test
int main() {
	SqQueue Q;
	int x;
	scanf("%d", &x);
	InitQueue(Q);
	EnQueue(Q, x);
	DeQueue(Q, x);
}

链式队列

  • 最适合做链队的链表是——带队首指针和队尾指针的非循环单链表

  • 最不适合做链队的链表是——只带队首指针的非循环双链表

  • 删除操作时——头尾指针都可能被修改(删除后队空时)

// 创建队列结构
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;

typeof struct{
	LinkNode *front, *rear;
}LinkQueue;
// 初始化
void InitQueue(LinkQueue &Q) {
	Q.front = (LinkNode *)malloc(sizeof(LinkNode));
	Q.rear = Q.front;
	Q.front -> next = NULL;
}

// 判空
bool IsEmpty(LinkQueue Q) {
	if(Q.front == Q.rear) return true;
	else return false;
}
void InQueue(LinkQueue &Q, ElemType x) {
	// 新建结点,链式一般不考虑队满的情况
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	s -> data = x;
	s -> next = NULL;
	Q.rear -> next = s;			// 插入队尾
	Q.rear = s;					// 队尾指针指向队尾
}
bool DeQueue(LinkQueue &Q, ElemType &x) {
	if(Q.front == Q.rear) return false; 	// 判空 也可以直接调用IsEmpty(Q)函数
	LinkNode *p = Q.front -> next;			
	x = p -> data;
	Q.front -> next = p -> next;
	if(Q.rear == p) 						// 出队后若为空队
		Q.rear = Q.front;
	free(p);								// 这个是一个经常会忘记的点,要把p释放了
	
	return true;
}

双端队列

这个代码实现可能会比较麻烦,But 只需要知道怎么操作就行了

  • 双端队列

在这里插入图片描述

  • 输出受限的双端队列

在这里插入图片描述

  • 输入受限的双端队列

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值