博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构之队列
阅读量:3899 次
发布时间:2019-05-23

本文共 2675 字,大约阅读时间需要 8 分钟。

什么是队列

队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列的特性总结为:先进先出。

这种特性在日常中类似于排队,先来的先进行服务!

队列的实现

我们使用链表实现队列,一个头节点和一个节点表示队列的头部和尾部。出队列和入队列的时间复杂度为 O(1)。空间复杂度为 O(n)

单向队列

队列是只允许在一端进行插入操作,在另外一段进行删除操作的线性表,队列不允许在中间部位进行操作

循环队列

为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列。循环队列是把顺序队列首尾相连,把存储队列元素的表从逻辑上看成一个环,成为循环队列。

双向队列

双端队列是一种两端都可以 删除元素和追加元素的线性结构。双端队列比普通的队列更加灵活。双端队列可以用双向链表实现。

单向队列的实现方式:

节点定义

#include 
#include
typedef struct Node{ // 节点的值 int val; // 节点的在一个节点 struct Node *next;} Node;typedef struct Queue{ /* data */ // 队列的头节点 Node *head; // 队列的尾节点 Node *tail; // 队列的元素数量 int len;} Queue;// 初始化队列Queue *init(){ // 申请空间 Queue *q = malloc(sizeof(Queue)); // 初始化成员属性 q->head = q->tail = NULL; q->len = 0; return q;}

入队操作

// 元素入队列void push(Queue *q, int val){    // 申请空间    Node *node = malloc(sizeof(Node));    node->val = val;    node->next = NULL;    // 判断队列是不是为空    if (q->len == 0)    {        // 直接赋值        q->head = q->tail = node;    }    else    {        // 将元素添加至队列末尾        q->tail->next = node;        q->tail = node;    }    // 长度 + 1    q->len++;}

出队操作

// 元素出队列int pop(Queue *q){    if (q->len > 0)    {        // 获取头节点的值        Node *h = q->head;        int val = h->val;        // 没有其他元素重置为NULL        if (h->next == NULL)        {            q->head = q->tail = NULL;        }        else        {            q->head = h->next;        }        // 释放节点空间        free(h);        q->len--;        return val;    }    return 0xFFFFFF;}

其他操作

// 返回队列的长度int size(Queue *q){    if (q == NULL)    {        return -1;    }    return q->len;}void printQueue(Queue *q){    if (q != NULL)    {        Node *h = q->head;        while (h != NULL)        {            printf("%d->", h->val);            h = h->next;        }        printf("\n");    }}// 销毁队列void destory(Queue *q){    if (q != NULL)    {        // 逐个释放节点的元素        Node *h = q->tail;        while (h != NULL)        {            free(h);            h = h->next;        }        // 释放队列        free(q);    }}

测试结果

int main(){    Queue *queue = init();    push(queue, 10);    push(queue, 11);    push(queue, 12);    push(queue, 13);    push(queue, 14);    printQueue(queue);    printf("%d\n", size(queue));    printf("%d\n", pop(queue));    printf("%d\n", size(queue));    printQueue(queue);    destory(queue);    return 0;}/*10->11->12->13->14->510411->12->13->14->*/

队列的应用

从队列的特性中我们可以看到,队列主要用在先来先服务的场景中。生活中与之相关的就是 12306 的候补买票了以及一些排队的场景下,这种顺序服务的思想在一些消息队列当中也有体现。

相关的代码我已上传到 gitlab:

此后的数据结构代码我都会上传在这个仓库中,需要的同学可以自己下载

感谢你能看到这里,欢迎关注我的 vx 公众号:元泱界 zz,学习更多的知识!我们下期再见!

转载地址:http://gtden.baihongyu.com/

你可能感兴趣的文章
visio画图-----如何克服两箭头交叉变形 及 箭头自动重绘?
查看>>
Android开发:安装NDK,移植OpenCV2.3.1,JNI调用OpenCV全过程
查看>>
“金9银10”2020年JVM高频率面试题整理,技术提升就差一个点!
查看>>
简简单单的分享2020常见的MySQL面试题MySQL与答案整理
查看>>
听说只有大厂的Android工程师才能全答对这20道题?我看你在吹牛哦!
查看>>
武功秘籍之 Redis 面试题全掌握,学完马上找面试官对线!
查看>>
50道!2020年!!MySQL高频数据库面试题解析,你都懂了吗?
查看>>
如何用Spring Boot加密配置文件中的特殊内容示例代码详解
查看>>
谈谈这些年面试官给大伙下的那些套,如何解?(面试技巧)
查看>>
5年开发经验的我被几条朋友圈打击到,点燃自己冲击阿里面经!
查看>>
5年工作经验的我放弃安逸,一份来自腾讯魔鬼面试的终极考验!
查看>>
学JAVA吗同学,这篇Sping boot 确定不了解下么?
查看>>
(3年+offer)华为技术岗面试初面+综合面试经验总结
查看>>
男默女泪,努力复习的我终于通过社招进入BAT工作了!(JAVA+JVM+框架+中间件+Spring干货分享)
查看>>
Python 导包
查看>>
dok_matrix
查看>>
theano 后端爆内存
查看>>
os.environ 和 keras.json
查看>>
后台面试经典问题-手写LRU算法
查看>>
Part-Guided Attention Learning for Vehicle Instance Retrieval
查看>>