队列(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.

【数据结构】之队列(C语言描述)的更多相关文章

  1. C语言学习书籍推荐《数据结构与算法分析:C语言描述(原书第2版)》下载

    维斯 (作者), 冯舜玺 (译者) <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行 ...

  2. 数据结构与抽象 Java语言描述 第4版 pdf (内含标签)

    数据结构与抽象 Java语言描述 第4版 目录 前言引言组织数据序言设计类P.1封装P.2说明方法P.2.1注释P.2.2前置条件和后置条件P.2.3断言P.3Java接口P.3.1写一个接口P.3. ...

  3. 数据结构与算法分析——C语言描述 第三章的单链表

    数据结构与算法分析--C语言描述 第三章的单链表 很基础的东西.走一遍流程.有人说学编程最简单最笨的方法就是把书上的代码敲一遍.这个我是头文件是照抄的..c源文件自己实现. list.h typede ...

  4. 最小正子序列(序列之和最小,同时满足和值要最小)(数据结构与算法分析——C语言描述第二章习题2.12第二问)

    #include "stdio.h" #include "stdlib.h" #define random(x) (rand()%x) void creat_a ...

  5. 《数据结构与算法分析——C语言描述》ADT实现(NO.00) : 链表(Linked-List)

    开始学习数据结构,使用的教材是机械工业出版社的<数据结构与算法分析——C语言描述>,计划将书中的ADT用C语言实现一遍,记录于此.下面是第一个最简单的结构——链表. 链表(Linked-L ...

  6. 《数据结构与算法分析-Java语言描述》 分享下载

    书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...

  7. 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

    表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...

  8. 《数据结构与算法分析——C语言描述》ADT实现(NO.02) : 队列(Queue)

    第三个结构——队列(Queue) 队列与上次的栈相反,是一种先进先出(FIFO)的线性表.写入时只暴露尾部,读取时只暴露头部. 本次只实现了数组形式的队列.原因是链表形式的队列极为简单,只需要实现简单 ...

  9. 使用链表实现队列------《数据结构与算法分析-C语言描述》

    经过ubuntu的gcc验证 一.头文件 que_link.h #ifndef _QUE_LINK_H_ #define _QUE_LINK_H_ struct que_record; typedef ...

  10. 使用数组实现队列----《数据结构与算法分析---C语言描述》

    一.h文件:my_que.h #ifndef _MY_QUE_H_ #define _MY_QUE_H_ struct QueRecord; typedef struct QueRecord* que ...

随机推荐

  1. ubuntu 制作本地yum仓库

    ubuntu 制作本地yum仓库 笔者: 张首富 W X: y18163201(请备注) qq群:895291458 时间:2019-01-31晚 今天到某银行进行软件部署的时候,碰到所有电脑都不允许 ...

  2. 上下文管理器及with的相关总结

    什么是上下文管理器 基本语法 with EXPR as VAR: BLOCK 概念 上下文表达式:with open('test.txt') as f: 上下文管理器:open('test.txt') ...

  3. [2018-03-06] 基于Django的轻量级CMS Mezzanine搭建笔记

    一丶什么是Mezzanine? 它是基于django的内容管理平台(),组成简单,可扩展性和定制性强,特别是个小型的个人博客系统.它也提供了类似wordpress的管理页面.博客发布.图片展示等功能, ...

  4. Django学习day2——Django安装与环境配置

    安装 Django 文章中python版本为3.65 这里以windows7为例,在pip目录下运行pip install Django就能安装django最新版本(本文为django2.2版本) 也 ...

  5. group:状压dp,轮廓线

    神仙题.但是难得的傻孩子cbx没有喊题解,所以也就难得的自己想出来了一个如此神仙的题. 如果是自己想的,说它神仙是不是有点不合适啊..? 反正的确不好像.关键就在于这个标签.颓完标签就差不多会了. % ...

  6. Ubuntu13.10编译android源码中遇到的问题

    1. jdk的版本不对 我开始安装的是最新的jdk7,但是编译时会出现jdk的版本

  7. python私有变量的分类

  8. 谷歌Chrome浏览器无法安装插件的解决方法(本文干货!)

    这个问题困扰了我很久,作为小白学习可能会用到谷歌插件,奈何谷歌也太变态,国内的环境无法正常登录谷歌账户.无法访问应用商店,而Chrome主版本号大于66的只能从Chrome应用商店下载并安装插件,各种 ...

  9. Spring mvc之源码 handlerMapping和handlerAdapter分析

    Spring mvc之源码 handlerMapping和handlerAdapter分析 本篇并不是具体分析Spring mvc,所以好多细节都是一笔带过,主要是带大家梳理一下整个Spring mv ...

  10. Mybatis自定义TypeHandler解决特殊类型转换问题

    我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象. 有时候使用MySQL存储数据,或者从MySQL中读取数据时,会有一些特殊需求