队列(Queue)是编程中最常用的数据结构之一。

  队列的特点是“先进先出”,就像食堂排队买饭一样,先来的人排在前面,后来的人排在后面;前面的人先买饭,买完饭后离开这个队列。这就是队列的原理,它可以进行入队列和出队列的操作,也就是说,队列限制用户只能在队列的前后两端进行操作,不能在中间进行操作。

  和线性表、栈相同,队列也有顺序的存储方式和链式的存储方式两种方式,分别称为顺序对和链队。与栈不同的是,队列可以在前后两个端点处进行增/删操作,因此,顺序队性能大大不如链队,链队是二者中比较常用的队列表示形式。

  下面的代码是使用 C语言 描述的链队的代码。

  队列的头文件Queue.h中的代码如下:

/**
* 队列(链式存储)
* 本程序中队列的存储方式:头节点->节点1->节点2->...->节点N,头结点中不存储数据
*/
#include <Constant.h> // 定义队列节点中数据的类型
typedef int ElemType; // 队列中节点的数据结构体
typedef struct QueueNode {
ElemType value;
struct QueueNode* nextNode;
} QueueNode; // 队列的结构体
typedef struct Queue {
QueueNode* data;
QueueNode* firstNode;
QueueNode* lastNode;
int length;
} Queue; // 初始化队列
Status initQueue(Queue* Q) {
Q->data = (QueueNode*)malloc(sizeof(QueueNode));
if(Q->data == NULL) {
printf("队列初始化失败!\n");
return FAILURE;
}
Q->data->nextNode = NULL;
Q->firstNode = NULL;
Q->lastNode = NULL;
Q->length = ;
return SUCCESS;
} // 销毁队列
Status destroyQueue(Queue* Q) {
QueueNode* node;
if(Q->data == NULL) {
printf("队列不存在,销毁失败!\n");
return FAILURE;
}
while(Q->data->nextNode != NULL) {
node = Q->data->nextNode;
Q->data->nextNode = node->nextNode;
free(node);
}
free(Q->data);
return SUCCESS;
} // 判断队列是否为空
Status isQueueEmpty(Queue* Q) {
if(Q->data == NULL) {
printf("队列不存在!\n");
exit();
}
if(Q->length == ) {
return TRUE;
}
return FALSE;
} // 清空队列
Status clearQueue(Queue* Q) {
QueueNode* node;
if(Q->data == NULL) {
printf("队列不存在,清空失败!\n");
return FAILURE;
}
while(Q->data->nextNode != NULL) {
node = Q->data->nextNode;
Q->data->nextNode = node->nextNode;
free(node);
}
return SUCCESS;
} // 获取队列中元素的个数
int getQueueSize(Queue* Q) {
if(Q->data == NULL) {
printf("队列不存在!\n");
exit();
}
return Q->length;
} // 查看队列中的第一个元素
QueueNode* getFirstElem(Queue* Q) {
if(Q->data == NULL) {
printf("队列不存在,获取第一个元素失败!\n");
return NULL;
}
if(Q->length == ) {
printf("队列是空队列,获取第一个元素失败!\n");
return NULL;
}
return Q->firstNode;
} // 查看队列中的最后一个元素
QueueNode* getLastElem(Queue* Q) {
if(Q->data == NULL) {
printf("队列不存在,获取最后一个元素失败!\n");
return NULL;
}
if(Q->length == ) {
printf("队列是空队列,获取最后一个元素失败!\n");
return NULL;
}
return Q->lastNode;
} // 元素入队列
Status appendElem(Queue* Q, ElemType e) {
QueueNode* newNode;
if(Q->data == NULL) {
printf("队列不存在,元素入队列失败!\n");
return FAILURE;
}
newNode = (QueueNode*)malloc(sizeof(QueueNode));
if(newNode == NULL) {
printf("元素入队列失败!\n");
return FAILURE;
}
newNode->value = e;
newNode->nextNode = NULL;
if(Q->data->nextNode == NULL) {
Q->data->nextNode = newNode;
Q->firstNode = newNode;
} else {
Q->lastNode->nextNode = newNode;
}
Q->lastNode = newNode;
Q->length++;
return SUCCESS;
} // 元素出队列
QueueNode* retrieveElem(Queue* Q) {
QueueNode* node;
if(Q->data == NULL) {
printf("队列不存在,元素出队列失败!\n");
return NULL;
}
if(Q->length == ) {
printf("队列是空队列,元素出队列失败!\n");
return NULL;
}
node = Q->data->nextNode;
Q->data->nextNode = node->nextNode;
Q->length--;
return node;
} // 遍历队列中的元素
void traverseQueue(Queue* Q) {
QueueNode* node;
if(Q->data == NULL) {
printf("队列不存在,遍历失败!\n");
exit();
}
if(Q->length == ) {
printf("队列是空队列,遍历失败!\n");
exit();
}
printf("遍历队列:");
node = Q->data;
while((node = node->nextNode) != NULL) {
printf("%-4d", node->value);
}
printf("\n");
} // 测试队列的方法
int testQueue() {
// 各种对象的声明
Queue queue;
QueueNode* node;
int i = ;
// 初始化队列
if(initQueue(&queue) == SUCCESS) {
printf("队列初始化成功!\n");
}
// 入队列
for(i = ; i <= ; i++) {
if(appendElem(&queue, i) == SUCCESS) {
printf("元素%d入队列成功!\n", i);
}
}
// 出队列
if((node = retrieveElem(&queue)) != NULL) {
printf("元素%d被移除队列\n", node->value);
}
// 查看队列中的第一个元素
if((node = getFirstElem(&queue)) != NULL) {
printf("队列中第一个元素的值是:%d\n", node->value);
}
// 查看队列中的最后一个元素
if((node = getLastElem(&queue)) != NULL) {
printf("队列中最后一个元素的值是:%d\n", node->value);
}
// 获取队列中元素的个数
printf("队列中元素的个数:%d\n", getQueueSize(&queue));
// 遍历队列中的元素
traverseQueue(&queue);
// 判断队列是否为空
printf("队列是否为空?%s\n", isQueueEmpty(&queue) == TRUE ? "是" : "否");
// 清空队列
if(clearQueue(&queue) == SUCCESS) {
printf("清空队列成功!\n");
}
// 销毁队列
if(destroyQueue(&queue) == SUCCESS) {
printf("队列销毁成功!\n");
}
}

  常量类 Constant.h 中定义了一些常量,其代码如下:

#include <stdio.h>
#include <stdlib.h> #define TRUE 1
#define FALSE 0 #define SUCCESS 1
#define FAILURE 0 typedef int Status;

  主函数所在的文件 main.c 中的代码如下:

#include <Queue.h>

int main() {
testQueue();
return ;
}

  运行结果如下:

队列初始化成功!
元素1入队列成功!
元素2入队列成功!
元素3入队列成功!
元素4入队列成功!
元素5入队列成功!
元素1被移除队列
队列中第一个元素的值是:1
队列中最后一个元素的值是:5
队列中元素的个数:4
遍历队列:2 3 4 5
队列是否为空?否
清空队列成功!
队列销毁成功! Process returned 0 (0x0) execution time : 1.743 s
Press any key to continue.

最新文章

  1. hyper容器网络相关源码分析
  2. Oracle使用小记
  3. Nginx 笔记与总结(16)nginx 负载均衡
  4. nginx负载均衡的实现
  5. c# 函数及out传值
  6. Docker容器环境下ASP.NET Core Web API
  7. &lt;转&gt;java编译问题:使用了未经检查或不安全的操作
  8. Git本地分支版本号过低导致的push错误 error: failed to push some refs to ... 及兴许amend
  9. OpenCv调用摄像头拍照代码
  10. 运维必备:Oracle自备份精简教程(linux及win)
  11. linux下处理excel里copy的某列的字符串,去除行末空格并添加特殊字段
  12. 控制结构(7) 程序计数器(PC)
  13. 在Visual Studio Code中开发Office Add-in
  14. How to Change Error Message Colors in Windows 10 PowerShell Console
  15. GMA Round 1 波动函数
  16. 内训--PPT演示技巧
  17. Tomcat-servlet基础
  18. C常用的字符串函数实现
  19. hdu-2865-polya+dp+矩阵+euler函数
  20. testMk

热门文章

  1. 九大Java性能调试工具,必备至少一款
  2. 【Java必修课】String.intern()原来还能这么用(原理与应用)
  3. [考试反思]1003csp-s模拟测试58:沉淀
  4. CSPS模拟 73
  5. Kettle(6.0) 参数方式连接数据库
  6. 使用Typescript重构axios(十一)——接口扩展
  7. JavaScript如何友好的操作的cookie
  8. 获取Centos的Docker CE
  9. Zabbix日志监控插件
  10. Python 面向对象-下篇