功能模块设计

编写一个程序实现链队列的各种基本运算,并在此基础上设计一个主程序,完成如下功能:

  • 初始化并建立链队列
  • 销毁链队列
  • 入队
  • 出队
  • 遍历链队列
  • 判断链队列是否为空
  • 清空链队列
  • 获取链队列长度
  • 获取链队列头元素

完整代码

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
//链队列的实现及常用操作测试
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
//链队列的数据结构
typedef int QElemType;
typedef struct QNode //队列节点
{
QElemType data;
struct QNode* next;
} QNode, * QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
} LinkQueue;

//函数声明列表
int InitQueue(LinkQueue* Q); //1 初始化链队列
int DestroyQueue(LinkQueue* Q); //2 销毁链队列
int EnQueue(LinkQueue* Q, QElemType e); //3 入队
int DeQueue(LinkQueue* Q, QElemType* e); //4 出队
int QueueEmpty(LinkQueue Q); //5 判断链队列是否为空
void ClearQueue(LinkQueue* Q); //6 清空链队列
int QueueLength(LinkQueue Q); //7 获取链队列长度
int GetHead(LinkQueue Q, QElemType* e); //8 获取队头元素
void QueueTraverse(LinkQueue Q); //9 遍历并输出链队列

//主函数
int main(void)
{
int n = 0, k = 0, i = 0;
QElemType d = 0;
LinkQueue Q;
srand((unsigned)time(NULL));
int status = InitQueue(&Q);
if (status) printf("队列初始化成功!\n");
else printf("队列初始化失败!\n");
printf("输入队列初始元素个数:");
scanf("%d", &n);
printf("队列初始化成功!\n执行%d次入队操作:\n", n);
for (i = 0; i < n; i++)
{
d = rand() % 90 + 10;
printf("第%-2d次:元素%d入队\n", i + 1, d);
//入队
EnQueue(&Q, d);
}
printf("打印当前队列:");
QueueTraverse(Q);
//获取队列长度
k = QueueLength(Q);
printf("\n当前队列长度为:%d\n\n", QueueLength(Q));
printf("执行%d次出队操作:\n", k / 2);
for (i = 0; i < k / 2; i++)
{
//出队
DeQueue(&Q, &d);
printf("第%-2d次:元素%d出队", i + 1, d);
printf("\t打印当前队列:");
QueueTraverse(Q);
}
//获取队头元素,保存到d中
n = GetHead(Q, &d);
if (n) printf("\n队头元素的值:%d\n", d);
printf("执行清空队列操作\n");
//清空队列
ClearQueue(&Q);
printf("清空队列后:q.front=%p q.rear=%p q.front->next=%p\n", Q.front, Q.rear, Q.front->next);
DestroyQueue(&Q);
printf("销毁队列后:q.front=%p q.rear=%p\n", Q.front, Q.rear);
return 0;
}

//功能1 初始化链队列
int InitQueue(LinkQueue* Q)
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q->front) return 0;
Q->front->next = NULL;
return 1; //初始化成功则返回1
}

//功能2 销毁链队列
int DestroyQueue(LinkQueue* Q)
{
while (Q->front)
{
//Q->rear指向Q->front的下一个节点
Q->rear = Q->front->next;
//释放Q->front所指节点
free(Q->front);
//Q->front指向Q->front的下一个节点
Q->front = Q->rear;
}
return 1;
}

//功能3 入队
int EnQueue(LinkQueue* Q, QElemType e)
{
//动态生成新节点
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
//生成失败则返回0
if (!p) return 0;
//将e的值赋给新节点
p->data = e;
//新节点的指针为空
p->next = NULL;
//原队尾节点的指针域为指向新节点
Q->rear->next = p;
//尾指针指向新节点
Q->rear = p;
//入队成功则返回1
return 1;
}

//功能4 出队
int DeQueue(LinkQueue* Q, QElemType* e)
{
//队列为空则返回0
if (Q->front == Q->rear) return 0;
//p指向队头节点
QueuePtr p = Q->front->next;
//队头元素赋给e
*e = p->data;
//队头节点指向下一个节点
Q->front->next = p->next;
//如果删除的是队尾节点,则修改队尾指针指向头节点
if (Q->rear == p) Q->rear = Q->front;
free(p);
//出队成功则返回1
return 1;
}

//功能5 判断链队列是否为空
int QueueEmpty(LinkQueue Q)
{
//如果队列为空则返回1
if (Q.front->next == NULL) return 1;
else return 0;
}

//功能6 清空链队列
void ClearQueue(LinkQueue* Q)
{
Q->front->next = NULL;
}

//功能7 获取链队列长度
int QueueLength(LinkQueue Q)
{
//计数器清0
int i = 0;
//p指向头节点
QueuePtr p = Q.front;
//如果p所指向的不是尾节点
while (p != Q.rear)
{
//则计数器加1
i++;
p = p->next;
}
return i;
}

//功能8 获取队头元素
int GetHead(LinkQueue Q, QElemType* e)
{
QueuePtr p;
if (Q.front == Q.rear) return 0;
//p指向队头节点
p = Q.front->next;
//将队头元素的值赋给e
*e = p->data;
return 1;
}

//遍历并输出队列(队头到队尾)
void QueueTraverse(LinkQueue Q)
{
QueuePtr p = Q.front->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

运行方法

  1. 新建一个cpp文件,命名为”main.cpp”。
  2. 将完整代码复制粘贴至”main.cpp”中。
  3. 利用Dev C++运行”main.cpp”即可。

运行结果

运行结果