数据结构学习笔记----队列
数据结构学习笔记----队列
队列也有两种存储表示,顺序表示和链式表示。
循环队列一一队列的顺序表示和实现
用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外,尚需附设两个整型变量 front 和 rear分别指示队列头元素及队列尾元素的位置(后面分别称为头指针和尾指针)。
队列的顺序存储结构
#define MAXQSIZE 100 //队列可能达到的最大长度
typedef struct
{
QElemType *base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
} SqQueue;
初始化创建空队列时,令 front = rear = 0 , 每当插入新的队列尾元素时,尾指针 rear增1; 每当删除队列头元素时, 头指针 front增1。
假溢出现象
指的是队列未满,但尾指针已经越界。不是真正因为满了才溢出,因此称为假溢出。
解决方法
改造成循环队列。
循环队列的实现方法--取模
队头元素是 J5, 在元素J6入队之前,在 Q.rear 的值为 5,当元素J6入队之后,通过 “模” 运算,Q.rear = (Q.rear + 1)%6, 得到 Q.rear 的值为 0, 而不会出现 “假溢出“ 状态。
循环队列的新问题
无法用之前的方法判断队空队满。对于循环队列不能以头尾指针的值是否相同来判别队列空间是 “满” 还是 “空”。
如何区别队满还是队空呢?
(1)少用一个元素空间
队空的条件: Q.front = Q.rear
队满的条件: (Q rear+ 1)%MAXQSIZE = Q.front
(2)另设一个标志位以区别队列是 “空” 还是 “满"。
常见的操作
- 初始化
- 入队
- 出队
- 求队长
链队--队列的链式表示和实现
链队是指采用链式存储结构实现的队列。
链式队列的操作很简单就是链表的插入删除操作等,再次不做具体介绍。
代码实现
#include "stdio.h"
#include "stdlib.h"
#define MAX 6
struct stack{
int a[MAX];
int rear;
int font;
}s;
void main()
{
int bh;
int e,i;
s.rear=0;
s.font=0;
printf("\n1.入队\n2.出对\n3.打印\n4.退出\n");
for(;;){
scanf("%d",&bh);
switch(bh){
case 1:
if((s.rear+1)%MAX==s.font){
printf("溢出\n");
break;
}else{
printf("输入入队数据:");
scanf("%d",&e);
s.a[s.rear]=e;/* 人为浪费一个空间 */
s.rear=(s.rear+1)%MAX;//尾部加一
}
break;
case 2:
if(s.rear==s.font){
printf("队列为空!\n");
break;
}else{
e=s.a[s.font];
s.font=(s.font+1)%MAX;
printf("出队的元素是%d\n",e);
}
break;
case 3:
if(s.rear==s.font){
printf("队列为空!\n");
break;
}
if(s.rear>s.font){
for(i=s.font;i<s.rear;i++){
printf("%d ",s.a[i]);
}
}else{
/* for(i=s.font;i<MAX;i++){
printf("%d ",s.a[i]);
}
for(i=0;i<s.rear;i++){
printf("%d ",s.a[i]);
}*/
for(i=s.font;i!=s.rear;i=(i+1)%MAX){
printf("%d ",s.a[i]);
}//两个都可以用这个
}
break;
case 0:
exit(0);
break;
default :
printf("输入功能编号有误!\n");
}
}
}
相关链接
https://www.cnblogs.com/TimVerion/p/11194552.html
https://www.cnblogs.com/bigsai/p/11363071.html
生活是一首长长的歌!