数据结构-队列

基本概念

队列是只允许在一端进行插入, 在另一端删除的线性表
在这里插入图片描述
队列的特点: 先进先出

队列的常见操作

InitQueue(&Q): 初始化队列, 构造一个空队列Q
DestoryQueue(&Q): 销毁队列, 销毁并释放队列Q所占用的内存空间
EnQueue(&Q,x): 入队, 若队列Q未满, 将x加入, 使之成为新的队尾
DeQueue(&Q,&x): 出队, 若队列Q非空, 删除队头元素, 并用x返回
GetHead(Q, &x): 读对头元素, 若队列Q非空, 则将队头赋值给x
QueueEmpty(Q) 判断队列空 , 若队列Q为空返回true, 否则返回false

队列的存储顺序

假设队列的元素个数最大不超过整数MAXSIZE, 所有的元素都具有同一数据类型QElemType, 则顺序队列类型SqQueue定义如下:

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

初始化队列

void InitQueue(SqQueue &Q){
	//初始化时队头和队尾指针指向0
	Q.rear = Q.front = 0;
}

判断队列是否为空

bool QueueEmpty(SqQueue Q){
	if(Q.rear==Q.front){
		return true;
	}else{
		return false;
	}
}

循环队列

有front==rear成立, 该条件可以作为队空的条件

能否用rear==MAXSIZE作为队满的条件呢?

不能, 在图(a)中, 队列不满, 但却满足该条件
这是入队会出现"上溢出", 队列仍存在可存放元素的空位置, 所以这种情况是假溢出
在这里插入图片描述

为充分使用顺序队列中的存储空间, 把顺序队列的首尾相连接, 形成一个环, 即循环队列

入队EnQueue(&Q, x)

入队, 若队列Q未满, 将x加入, 使之成为新的队尾

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

入队

bool EnQueue(SqQueue Q, ElemType x){
	if(队列已满){
		return false;
	}
	Q.data[Q.rear]=x;//将x插入队尾
	Q.rear=Q.rear+1;//队尾指针后移
	return true;
}

循环队列的入队

bool EnQueue(SqQueue Q, ElemType x){
	if(Q.front == Q.rear){//队列已满
		return false;
	}
	Q.data[Q.rear]=x;//将x插入队尾
	Q.rear=(Q.rear+1)%MaxSize;//队尾指针后移
	return true;
}
循环队列基本操作的实现

初始化空队
Q.front = Q.rear = 0;

入队
Q.rear=(Q.rear+1)%MaxSize;

出队
Q.front=(Q.front+1)%MaxSize;

队空条件
Q.front == Q.rear;//由于出队的Q.front追上了Q.rear

队满条件
Q.front == Q.rear;//由入出队的Q.rear追上了Q.front

如何区分循环队列的对空、队满

在入队时少用一个数据元素空间, 以队尾指针加1等于队头指针判断队满
即队满条件为:
(Q.rear+1)%MaxSize==Q.front

队空条件仍为
Q.rear == Q.front

队列元素个数
( rear + MaxSize - front ) % MaxSize

循环队列初始化队列
Status InitQueue(SqQueue &Q){
	Q.base = (QElemType *) malloc (MaxSize * sizeof(QElemType ));
	if(!Q.base){
		exit(OVERFLOW);
	}
	Q.front = Q.rear = 0;
	return OK;
}

在这里插入图片描述

求队列的长度
int QueueLength(SqQueue Q){
	return (Q.rear - Q.front + MaxSize)%MaxSize;
}
入队列

判断队列是否为空

bool QueueEmpty(SqQueue Q){
	if(Q.rear==Q.front){
		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;//队尾指针加1取模
	return true;
}

在这里插入图片描述

出队列
int DeQueue(SqQueue &Q, QEmleType &e){
	if(Q.front==Q.rear){
		return ERROR;//对空
	}
	e=Q.base[Q.front];
	Q.front=(Q.front+1)%MaxSize;//队头位置发生变化
	return OK;
}

队列的链式存储

typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;
typedef struct {//链式队列
	LinkNode *front , *rear;//队列的对头和队尾指针
}LinkQueue;

在这里插入图片描述

初始化队列InitQueue(&Q)(带头结点)
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;
typedef struct {//链式队列
	LinkNode *front , *rear;//队列的对头和队尾指针
}LinkQueue;

初始化队列

void InitQueue(LinkQueue &Q){
	//初始化时,front,rear都指向头结点
	Q.front=Q.rear=(LinkQueue*)malloc(sizeof(LinkNode));//申请结点空间
	Q.front->next=NULL;
}

判断对列是否为空

bool IsEmpty (LinkQueue Q){
	if(Q.front==Q.rear){
		return true;
	}else{
		return false;
	}
}
初始化队列InitQueue(&Q)(不带头结点)

初始化队列(不带头结点)

void InitQueue(LinkQueue &Q){
	//初始化时,front,rear都指向NULL
	Q.front=NULL;
	Q.rear=NULL;
}

判断对列是否为空

bool IsEmpty (LinkQueue Q){
	if(Q.front==NULL){
		return true;
	}else{
		return false;
	}
}
入队列EnQueue(&Q , e)(带头结点)

新元素入队(带头结点)

void EnQueue(LinkQueue &Q, ElemType x){
	LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
	s->data=x;
	s->next=NULL;
	Q.rear->next=s;//新结点插入到rear之后
	Q.rear=s;//修改表尾指针
}

在这里插入图片描述
在这里插入图片描述

入队列EnQueue(&Q , e)(不带头结点)
void EnQueue(LinkQueue &Q, ElemType 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;//新结点插入到rear之后
		Q.rear=s;//修改表尾指针
	}	
}
出队列EnQueue(&Q , e)(带头结点)
bool DeQueue(LinkQueue Q, ElemType &x){
	if(Q.front==Q.rear){
		return false;//空队
	}
	LinkNode *p = Q.front->next;
	x=p->data;//用变量x返回队头元素
	Q.front->next = p->next;//修改头结点的next指针
	if(Q.rear==p){//此次是最后一个结点出队
		Q.rear=Q.front;//修改rear指针
	}
	free(p);//释放结点空间
	return true;
}

在这里插入图片描述
当删成最后一个结点
在这里插入图片描述

出队列EnQueue(&Q , e)(不带头结点)
bool DeQueue(LinkQueue Q, ElemType &x){
	if(Q.front==Q.rear){
		return false;//空队
	}
	LinkNode *p = Q.front;
	x=p->data;//用变量x返回队头元素
	Q.front = p->next;//修改头结点的next指针
	if(Q.rear==p){//此次是最后一个结点出队
		Q.rear=NULL;
		Q.front=NULL;
	}
	free(p);//释放结点空间
	return true;
}

在这里插入图片描述
在这里插入图片描述

双端队列

只允许从两端插入, 两端删除的线性表
在这里插入图片描述
输入受限的双端队列: 只允许从一端插入, 两端删除的线性表

在这里插入图片描述
输出受限的双端队列: 只允许从两端插入, 一端删除的线性表
在这里插入图片描述

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

稻田里展望者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值