-
Notifications
You must be signed in to change notification settings - Fork 1
/
linkqueue1.c
276 lines (195 loc) · 6.48 KB
/
linkqueue1.c
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/*
* 程序名:linkqueue1.c,此程序演示队列的链表实现(带头结点)。
* 作者:C语言技术网(www.freecplus.net) 日期:20201230
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int ElemType; // 自定义队列的数据元素为整数。
typedef struct LNode
{
ElemType data; // 存储队列中的元素。
struct LNode *next; // next指针。
}LNode;
typedef struct
{
LNode *front,*rear; // 队列的头指针和尾指针。
}LinkQueue,*PLinkQueue;
// 队列QQ的初始化操作。
int InitQueue(PLinkQueue QQ);
// 销毁队列QQ。
void DestroyQueue(PLinkQueue QQ);
// 清空队列。
void Clear(PLinkQueue QQ);
// 元素入队,返回值:0-失败;1-成功。
int InQueue(PLinkQueue QQ, ElemType *ee);
// 打印队列中全部的元素。
void PrintQueue(PLinkQueue QQ);
// 求队列的长度,返回值:>=0-队列QQ元素的个数。
int Length(PLinkQueue QQ);
// 判断队列是否已满,链式队列不存在队满的说法。
int IsFull(PLinkQueue QQ);
// 判断队列是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PLinkQueue QQ);
// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PLinkQueue QQ, ElemType *ee);
// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PLinkQueue QQ, ElemType *ee);
int main()
{
LinkQueue QQ; // 创建队列。
memset(&QQ,0,sizeof(LinkQueue));
InitQueue(&QQ); // 初始化队列。
ElemType ee; // 创建一个数据元素。
printf("元素(1、2、3、4、5、6、7、8、9、10)入队。\n");
ee=1; InQueue(&QQ, &ee);
ee=2; InQueue(&QQ, &ee);
ee=3; InQueue(&QQ, &ee);
ee=4; InQueue(&QQ, &ee);
ee=5; InQueue(&QQ, &ee);
ee=6; InQueue(&QQ, &ee);
ee=7; InQueue(&QQ, &ee);
ee=8; InQueue(&QQ, &ee);
ee=9; InQueue(&QQ, &ee);
ee=10; InQueue(&QQ, &ee);
printf("队列的长度是%d\n",Length(&QQ));
PrintQueue(&QQ);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
if (OutQueue(&QQ,&ee)==1) printf("出队的元素值为%d\n",ee);
printf("队列的长度是%d\n",Length(&QQ));
PrintQueue(&QQ);
printf("元素(11、12、13、14、15)入队。\n");
ee=11; InQueue(&QQ, &ee);
ee=12; InQueue(&QQ, &ee);
ee=13; InQueue(&QQ, &ee);
ee=14; InQueue(&QQ, &ee);
ee=15; InQueue(&QQ, &ee);
printf("队列的长度是%d\n",Length(&QQ));
PrintQueue(&QQ);
// 只查看队头元素的值,元素不出队。
if (GetHead(&QQ,&ee)==1) printf("队头的元素值为%d\n",ee);
DestroyQueue(&QQ); // 销毁队列QQ。
return 0;
}
// 初始化队列,返回值:0-失败;1-成功。
int InitQueue(PLinkQueue QQ)
{
LNode *head = (LNode *)malloc(sizeof(LNode)); // 分配头结点。
if (head == NULL) return 0; // 内存不足,返回失败。
head->next=NULL; // 头结点的下一结点暂时不存在,置空。
QQ->front=QQ->rear=head;
return 1;
}
// 清空队列。
void Clear(PLinkQueue QQ)
{
if (QQ == NULL) return; // 判断队列是否存在。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return; } // 队列未初始化。
// 清空队列QQ是指释放链表全部的数据结点,但保留头结点。
LNode *tmp=QQ->front->next,*tmpnext;
while(tmp!=NULL)
{
tmpnext=tmp->next; // tmpnext保存下一结点的地址。
free(tmp); // 释放当前结点。
tmp=tmpnext; // tmp指针移动到下一结点。
}
QQ->rear=QQ->front; // 尾指针指向头结点。
QQ->front->next=NULL;
}
// 求队列的长度,返回值:>=0-队列QQ元素的个数。
int Length(PLinkQueue QQ)
{
if (QQ == NULL) return 0; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return 0; } // 队列未初始化。
LNode *pp=QQ->front->next; // 头结点不算,从第1个结点开始。
int length=0;
while (pp != NULL) { pp=pp->next; length++; }
return length;
}
// 销毁队列QQ。
void DestroyQueue(PLinkQueue QQ)
{
if (QQ == NULL) return; // 检查空指针。
// 销毁队列QQ是指释放链表全部的结点,包括头结点。
LNode *tmp=QQ->front,*tmpnext;
while(tmp!=NULL)
{
tmpnext=tmp->next; // tmpnext保存下一结点的地址。
free(tmp); // 释放当前结点。
tmp=tmpnext; // tmp指针移动到下一结点。
}
QQ->front=QQ->rear=NULL; // 防止野指针。
return;
}
// 判断队列是否为空,返回值:1-空,0-非空或失败。
int IsEmpty(PLinkQueue QQ)
{
if (QQ == NULL) return 0; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return 0; } // 队列未初始化。
if (QQ->front->next == NULL) return 1;
return 0;
}
// 判断队列是否已满,链式队列不存在队满的说法。
int IsFull(PLinkQueue QQ)
{
if (QQ == NULL) return 0; // 检查空指针。
return 1;
}
// 元素入队,返回值:0-失败;1-成功。
int InQueue(PLinkQueue QQ, ElemType *ee)
{
if ( (QQ == NULL) || (ee == NULL) ) return 0; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return 0; } // 队列未初始化。
LNode *tmp = (LNode *)malloc(sizeof(LNode)); // 分配一个结点。
if (tmp == NULL) return 0; // 内存不足,返回失败。
// 考虑数据元素为结构体的情况,这里采用了memcpy的方法而不是直接赋值。
memcpy(&tmp->data,ee,sizeof(ElemType));
tmp->next=NULL;
// 把tmp追加到QQ->rear之后。
QQ->rear->next=tmp;
QQ->rear=tmp;
return 1;
}
// 打印队列中全部的元素。
void PrintQueue(PLinkQueue QQ)
{
if (QQ == NULL) return; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return; } // 队列未初始化。
LNode *pp=QQ->front->next; // 从第1个数据结点开始。
while (pp != NULL)
{
printf("%-3d", pp->data); // 如果元素ee为结构体,这行代码要修改。
pp=pp->next;
}
printf("\n");
}
// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PLinkQueue QQ, ElemType *ee)
{
if ( (QQ == NULL) || (ee == NULL) ) return 0; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return 0; } // 队列未初始化。
if (IsEmpty(QQ) == 1) { printf("队列为空。\n"); return 0; }
LNode *tmp=QQ->front->next;
memcpy(ee,&tmp->data,sizeof(ElemType));
QQ->front->next=tmp->next;
// 如果出队的是最后一个结点。
if (QQ->rear==tmp) QQ->rear=QQ->front;
free(tmp);
return 1;
}
// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PLinkQueue QQ, ElemType *ee)
{
if ( (QQ == NULL) || (ee == NULL) ) return 0; // 检查空指针。
if (QQ->front == NULL) { printf("队列QQ未初始化。\n"); return 0; } // 队列未初始化。
if (IsEmpty(QQ) == 1) { printf("队列为空。\n"); return 0; }
memcpy(ee,&QQ->front->next->data,sizeof(ElemType));
return 1;
}