队列的顺序实现
廖家龙 用心听,不照做


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>

#define MaxSize 10 //定义队列中元素的最大个数

//队列的顺序实现【front指向队头元素,rear指向队尾元素的后一个位置;还有一种情况是rear指向队尾元素】
typedef struct{
int data[MaxSize]; //用静态数组存放队列元素
int front,rear; //队头指针和队尾指针

//int size; //第二种判断队列已满/已空的方法,定义一个size:队列当前长度
//int tag; //第三种判断队列已满/已空的方法:最近进行的是删除还是插入
}SqQueue;

//初始化队列
void InitQueue(SqQueue *Q){
Q->front=Q->rear=0; //初始时队头、队尾指针指向0

//Q->size=0; //第二种判断队列已满/已空的方法,插入成功size++,删除成功size--,队空条件:size==0,队满条件:size==MaxSize

//Q->tag=0; //第三种判断队列已满/已空的方法:每次删除操作成功时,都令tag=0,每次插入操作成功时都令tag=1;只有删除操作,才可能导致队空,只有插入操作,才可能导致队满;队空条件:front==rear && tag==0,队满条件:front==rear && tag==1
}

//判断队列是否为空
bool QueueEmpty(SqQueue *Q){
if(Q->rear==Q->front){ //队空条件
return true;
}
else{
return false;
}
}

//循环队列:入队操作
bool EnQueue(SqQueue *Q,int x){
if((Q->rear+1)%MaxSize == Q->front){ //队列已满的条件:队尾指针的再下一个位置是队头,代价:牺牲一个存储单元
return false; //队满则报错
}
Q->data[Q->rear]=x; //新元素插入队尾
Q->rear=(Q->rear+1)%MaxSize; //队尾指针+1取模,用模运算将存储空间在逻辑上变成了“环状”

//这是rear指向队尾元素的情况
//Q->rear=(Q->rear+1)%MaxSize;
//Q->data[Q->rear]=x;
return true;
}

//循环队列:出队操作
//出队:删除一个队头元素,并用x返回
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;
}

//获取队头元素的值,用x返回
bool GetHead(SqQueue *Q,int *x){
if(Q->rear==Q->front){
return false;
}
(*x)=Q->data[Q->front];
return true;
}

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

int main(){
SqQueue Q; //声明一个队列,顺序存储

InitQueue(&Q);

//...后续操作
}