1 //队列是另一种限定存取位置的线性表。它只允许在表的一端插入,在另一端删除。允许插入的一端叫做队尾,允许删除的一端叫做队头。每次
2 //在队尾加入新元素,最先进入队列的元素最先退出队列。先进先出
3
4
5 //循环队列:
6
7 //循环队列,其首尾相接,当队头指针front和队尾指针rear进到maxSize-1后,再前进一个位置九自动到0,这样可以利用整除取余来实现
8 //队头指针进1:front = (front + 1)%maxSize
9 //队尾指针进1:rear = (rear + 1)%maxSize
10
11 //循环队列的结构定义
12 typedef int QElemType;
13 #define maxSize 20 //循环队列的容量
14 typedef struct CircQueue
15 {
16 QElemType elem[maxSize]; //数组元素
17 int front, rear; //队头指针和队尾指针(数组下标)
18 };
19
20 //循环队列初始化
21 void InitQueue(CircQueue& Q)
22 {//循环队列初始化:令队头指针和队尾指针归零
23 Q.front = Q.rear = 0;
24 }
25
26 //循环队列插入
27 void EnQueue(CircQueue& Q, QElemType x)
28 {//若对列不满,则将元素x插入到队尾,函数返回1,否则函数返回0,不能进队列
29 if((Q.rear + 1)%maxSize == Q.front) return 0; //队列满则不能插入,函数返回0
30 Q.elem[Q.rear] = x; //按照队尾指针指示位置插入
31 Q.rear = (Q.rear + 1)%maxSize; //队尾指针进1
32 return 1; //插入成功,函数返回1
33 }
34
35 //循环队列删除
36 int DeQueue(CircQueue& Q, QElemType& x)
37 {//若队列不空,则函数推掉一个队头元素并通过引用型参数x返回,函数返回1,否则函数返回0,此时x的值不可引用
38 if(Q.front == Q.rear) return 0; //队列空则不能删除,函数返回0
39 x = Q.elem[Q.front];
40 Q.front = (Q.front + 1)%maxSize; //队头指针进1
41 return 1; //删除成功,函数返回1
42 }
43
44 //返回队头元素的值
45 int GetQueue(CircQueue& Q, QElemType& x)
46 {//若对列不空,则函数通过引用型参数x返回队头元素的值,函数返回1,否则函数返回0,此时x的值不可引用
47 if(Q.front == Q.rear) return 0;//返回队头元素的值
48 x = Q.elem[Q.front];
49 return 1;
50 }
51
52 //判断队列是否为空
53 int QueueEmpty(CircQueue& Q)
54 {//判队列空否。若队列空,则函数返回1,否则返回0
55 return Q.front == Q.rear; //返回Q.front == Q.rear 运算结果
56 }
57
58 //判断队列满否
59 int QueueFull(CircQueue& Q)
60 {//判断队列满否。若队列满,则函数返回1,否则返回0
61 return (Q.rear + 1)%maxSize == Q.front; //返回(Q.rear + 1)%maxSize == Q.front运算结果
62 }
63
64 //求队列元素个数
65 int QueueSize(CircQueue& Q)
66 {//求队列元素个数
67 return (Q.rear - q.front + maxSize)%maxSize;
68 }
71 //链式队列
72
73 //链式队列是对列基于单链表的存储表示,在单链表的每一个结点中有两个域:data域存放队列元素的值,link域存放单链表下一个结点的地址
74 //队列的头指针指向单链表的头结点,但实际队头结点在头结点后面的首元结点,意味着队列的头元素放在单链表的首元结点内,若要从队列中
75 //退出一个元素,必须从单链表中删去首元结点。而队列的队尾指针指向单链表的尾结点,存放新元素的结点应插在队列的队尾。
76
77 //链式队列的结构定义
78 typedef struct node //链式队列结点定义
79 {
80 QElemType data; //结点数据
81 struct node* link; //结点链接指针
82 }LinkNode;
83 typedef struct LinkQueue //链式队列定义
84 {
85 LinkNode *front, *rear; //队头和队尾指针
86 }
87
88 //链式队列初始化
89 void InitQueue(LinkQueue& Q)
90 {//队列初始化:创建链式队列的头结点,令队头指针和队尾指针指向头结点
91 Q = new LinkNode; //创建链式队头结点
92 if(!Q){cerr<<"存储分配失败!\n"; exit(1);}
93 Q.front == Q.rear == Q; //队头与队尾指针初始化
94 }
95
96 //链式队列的插入:即入队列
97 int EnQueue(LinkQueue& Q, QElemType x)
98 {//进对列:将新元素x插入到队列的队尾(链尾)
99 Q.rear->link = new LinkNode; //创建新结点
100 if(!Q.rear->link){cerr<<"存储分配失败!\n"; exit(1);}
101 Q.rear = Q.rear->link; //新结点成为新的队尾
102 Q.rear->data = x; Q.rear->link = NULL; //将插入的新结点值赋给队尾元素,队尾下一个元素指向空
103 return 1; //插入成功
104 }
106 //链式队列的删除:即出对列
107 int DeQueue(LinkQueue& Q, QElemType& x)
108 {//出对列:如果队列不空,将队头结点从链式队列中删去,并通过引用向参数x返回被删元素的值,同时函数返回1;若队列空,则函数返回0,
109 //此时x的值不可引用
110 if(!Q.front->link) return 0; //队列空则返回0
111 LinkNode *p = Q.front->link; //队列不空,保存队头结点地址
112 x = p->data;
113 Q.front->link = p->link; //队头修改
114 delete p; //释放元对头结点
115 return 1; //函数返回1
116 }
117
118 //读取队头元素的值
119 int GetFront(LinkQueue& Q, QElemType& x)
120 {//读取队头元素的值:若对列不空,则函数通过引用型参数x返回队列元素的值,函数返回1;若队列空,则函数返回0,且x的值不可引用
121 if(!Q.front->link) return 0; //队列空则返回0
122 x = Q.front->link->data; //取队头元素中的数据值
123 return 1;
124 }
125
126 //判断队列是否为空
127 int QueueEmpty(LinkQueue& Q)
128 {//判队列空否:队列空则函数返回1,否则函数返回0
129 return Q.front->link == NULL;
130 }
131
132 //求队列元素个数
133 int QueueSize(LinkQueue& Q)
134 {
135 LinkNode *p = Q.front->link; int k = 0;
136 while(p != NULL)
137 {
138 p = p->link;
139 k++;
140 }
141 return k;
142 }