一、队列的基本概念:
和栈一样,队列也是操作受限的线性表,只允许在表的一段插入,在另一端删除。操作特性是先进先出。
队头(front):允许删除或者说允许进行出队操作的一端。
队尾(rear):允许插入或者说允许入队的一端。
二、队列的顺序存储结构:
队列的顺序实现和顺序表一样是分配了一块连续的存储单元用来存放数据元素。队列的顺序实现需要用到两个指针:队头指针front指向队头元素,队尾指针rear指向队尾元素的下一个位置。
在初始状态时(队空):Q.front=Q.rear=0
入队操作:队不满时,先送值到队尾,再把队尾指针加1
出队操作:队不为空时,先把值赋出来,再队头指针加一
三、循环队列:
typedef struct Squeue
{
int data[MAXSIZE];
int front, rear;
int size = 0;
}Squeue;
把存储元素的表从逻辑上视为一个环,当队首指针Q.front=MaxSize-1后,在前进一个位置就自动到零,这个过程是通过除法取余运算来实现的。
初始时:Q.rear = Q.front = 0
不管是入队还是出队,指针都顺时针进一
队首指针进一:Q.front = (Q.front+1)%Maxsize
队尾指针进一:Q.rear = (Q.rear+1)%Maxsize
为了区分是队空还是队满,一般会选择用牺牲一个存储单元的方法,约定用“队头指针在队尾指针的下一位”作为队满的标志。
队满:(Q.rear+1)%Maxsize==Q.front
队空: Q.front ==Q.rear
队列中元素的个数:(Q.rear-Q.front+Maxsize)%Maxsize
四、循环队列的基本操作:
初始化时,Q.rear = Q.front = 0
void InitQueue(Squeue &Q){//初始化
Q.rear = Q.front = 0;
}
判空:在类型中增设了一个存放元素个数的数据成员size
bool isEmpty(Squeue Q){//判断是否为空
if(Q.size==0){
printf("empty!");
return false;
}
else if(Q.size==MAXSIZE){
printf("full!");
return false;
}
else
{
return true;
}
}
入队:若队列不满,则队尾指针加一(通过取模使到maxsize-1时,再进一位能回到0)
bool InQueue(Squeue &Q,int x){//入队
if(Q.size==MAXSIZE-1){
printf("队满\n");
return false;
}
else{ Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MAXSIZE;
Q.size++;
return true;
}
}
出队:若队列不为空,则队头指针加一,同样也是以取模的方式
bool outQueue(Squeue &Q,int &x){//出队
if (Q.size==0){
printf("\nthe queue is emtpy!");
return false;
}
else{
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
Q.size--;
return true;}
}
遍历:循环取值,从front取到rear保证遍历到每个元素
bool showElem(Squeue Q){//遍历所有元素
for (int i = Q.front; i < Q.rear;i++){
printf("%d\t", Q.data[i]);
}
printf("\n");
return true;
}
取队头元素:直接把front拿出来
bool findHead(Squeue Q){
printf("the head elem is:%d",Q.data[Q.front]);
printf("\n");
return true;
}
完整代码
#include"stdio.h"
#define MAXSIZE 10
typedef struct Squeue
{
int data[MAXSIZE];
int front, rear;
int size = 0;
}Squeue;
Squeue Q;
void InitQueue(Squeue &Q){//初始化
Q.rear = Q.front = 0;
}
bool isEmpty(Squeue Q){//判断是否为空
if(Q.size==0){
printf("empty!");
return false;
}
else if(Q.size==MAXSIZE){
printf("full!");
return false;
}
else
{
return true;
}
}
bool InQueue(Squeue &Q,int x){//入队
if(Q.size==MAXSIZE-1){
printf("队满\n");
return false;
}
else{ Q.data[Q.rear] = x;
Q.rear = (Q.rear + 1) % MAXSIZE;
Q.size++;
return true;
}
}
bool outQueue(Squeue &Q,int &x){//出队
if (Q.size==0){
printf("\nthe queue is emtpy!");
return false;
}
else{
x = Q.data[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
Q.size--;
return true;}
}
bool showElem(Squeue Q){//遍历所有元素
for (int i = Q.front; i < Q.rear;i++){
printf("%d\t", Q.data[i]);
}
printf("\n");
return true;
}
bool findHead(Squeue Q){
printf("the head elem is:%d",Q.data[Q.front]);
printf("\n");
return true;
}
int main(){
InitQueue(Q);
int choice = 0;
int x;
bool flag = true;
printf("按1入队新元素\n");
printf("按2出队元素\n");
printf("按3取队头元素\n");
printf("按4遍历队列\n");
printf("按5退出\n");
while(flag==true){
printf("请选择你要使用的功能:");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("please insert the elem:");
scanf("%d", &x);
InQueue(Q, x);
printf("insert success!");
break;
case 2:
outQueue(Q, x);
printf("\nthe elem which outfrom is:%d", x);
printf("\tnow the queue is :");
showElem(Q);
break;
case 3:
findHead(Q);
break;
case 4:
showElem(Q);
break;
case 5:
flag = false;
break;
}
}
return 0;
}