队列定义和顺序、链式

 

目录

定义:

基本操作:创销增删改查

顺序实现:

栈满情况

代码:

顺序实现

小结1:

链式实现

小结2:

 双端队列

下一篇:栈的括号匹配应用


定义:

队列(Queue)是只允许在一段进行插入(入队),在另一端进行删除(出队)的线性表

先入先出(FIFO)

重要术语:队头、队尾、空队列

 

基本操作:创销增删改查

 

 

 

 

顺序实现:

栈满情况

代码:

顺序实现

#include<bits/stdc++.h>
//queue
using namespace std;
#define MaxSize 10
typedef struct{	
	int data[MaxSize];
	int front,rear;//队头和队尾 
}SqQueue;
//为了使得最后一个空间不被浪费可以设置一个size来记录当前队列长度 
//或者设置一个tag,当tag=0表示最近做的是删除,1表示插入
//只有删除才能导致队空,只有插入才能导致队满 
//那么队满的判断条件就是front==rear&&tag==1
//那么队空的判断条件就是front==rear&&tag==0
//初始化
void initQueue(SqQueue &Q){
	//初始化时队头、队尾指针指向0
	Q.front=0;
	Q.rear=0;
}
//若队尾指针指向最后一个元素,则初始化时要使rear=MaxSize-1
//插入时也要先执行Q.rear=(Q.rear+1)%MaxSize; 
//判断队满也可以选择牺牲一个存储单元,或者增加辅助变量 
//判空 
bool Empty(SqQueue Q){
	return Q.front==Q.rear;
}
//入队
bool EnQueue(SqQueue &Q,int x){
	//如果rear指针的下一个单元是front则证明队满
	//又由于如果占用rear指针栈满前的一个单元就会使得rear=front
	//造成栈空假象,所以要浪费一个存储空间 
	if((Q.rear+1)%MaxSize==Q.front)
		return false;
	Q.data[Q.rear=x]=x;
	//通过取模运算将存储空间逻辑上变成环状,解决假溢出 
	Q.rear=(Q.rear+1)%MaxSize;
} 
//出队
bool DeQueue(SqQueue &Q,int &x){
	if(Q.rear==Q.front)
		return false;
	x=Q.data[Q.front];
	Q.front=(Q.front+1)%MaxSize;
	return true;
} 
//获取头元素的值
bool GetHead(SqQueue &Q,int &x){
	if(Q.front==Q.rear)return false;
	x=Q.data[Q.front];
	return true;
} 
//求队长
int GetLength(SqQueue Q){
	return (Q.rear+MaxSize-Q.front)%MaxSize;	
} 

 

小结1:

 

 

链式实现

//链式实现
//链式队列节点 
typedef struct LinkNode{
	int data;
	struct LinkNode *next;
}LinkNode; 
//链式队列 
typedef struct{
	LinkNode *front,*rear;//队头指针、队尾指针 
}LinkQueue; 
//同样也分为带和不带头结点
//初始化,带头结点
void InitLinkQueue(LinkQueue &Q){
	//队头、队尾都指向头结点 
	Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
	//头结点next=NULL 
	Q.front->next=NULL;
} 
//判空
bool isEmpty(LinkQueue Q){
	return Q.front==Q.rear;
} 
//入队带头结点
void EnLinkQueue(LinkQueue &Q,int x){
	LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
	s->data=x;
	s->next=NULL;
	Q.rear->next=s;//新元素插入到rear之后 
	Q.rear=s;//表尾指针指向新元素 
}
//出队带头结点 
bool DeLinkQueue(LinkQueue &Q,int &x){
	if(Q.front==Q.rear)return false;
	LinkNode *p=Q.front->next;
	x=p->data;
	Q.front->next=p->next;
	if(Q.rear==p)//若是最后一个元素出队 
		Q.rear=Q.front;
	free(p);
	return true;
}
//初始化不带头结点
void InitLinkQueueWithoutHead(LinkQueue &Q){
	Q.front=NULL;
	Q.rear=NULL;
} 
bool isEmptyWithoutHead(LinkQueue Q){
	return Q.front==NULL;//或rear=NULL 
}
void EnLinkQueueWithoutHead(LinkQueue &Q,int x){
	LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode));
	s->data=x;
	s->next=NULL;
	//如果队空,第一个结点要特殊处理 
	if(Q.front==NULL){
		Q.front=s;//表头表尾都指向第一个元素 
		Q.rear=s;
	}else{
		Q.rear->next=s;
		Q.rear=s;
	}
}
bool DeLinkQueueWithoutHead(LinkQueue &Q,int &x){
	if(Q.front==NULL)return false;
	LinkNode *p=Q.front;
	x=Q.front->data;
	Q.front=p->next;
	if(Q.rear==p)
	{
		Q.front=NULL;
		Q.rear=NULL;
	}
	free(p);
	return true;
}
//链式存储一般不会队满,除非内存不足 

小结2:

 双端队列

定义:只允许从两端插入、两段删除的线性表

还能推广出输入受限的双端队列(只允许从一段插入)、输出受限的双端队列(只允许从一端删除)

 

考点:判断输出序列是否合法,哪些合法

 

小结:

 

猜你喜欢

转载自blog.csdn.net/weixin_46919419/article/details/114444685