链式队列的优化

上一节我们讲了一下顺序队列的优化,本节我们讲一下链式队列的优化。同理,我们得先知道链式队列的瓶颈在哪里。

链式队列的瓶颈

1.线性表的第一个元素作为队头,线性表的最后一个元素作为队尾;2.入队的新元素是在线性表的最后,时间复杂度为O(n);

3.出队的元素即链表的第一个元素,时间复杂度O(1)。
问题:如何将入队操作的时间复杂度降低到O(1)?

链式队列的优化方案
1.定义rear指针始终指向链表中的最后一个元素,入队时将新元素通过rear插入队尾,且将rear指向新元素;

2.定义front指针使其始终指向链表中的第一个元素,出队时将队头元素返回,且front指向front下一个元素。

链式队列的关键状态
空队列状态:front == NULL, rear == NULL;
关键操作
1.入队:

1.1.rear->next= node;

1.2.rear =node;

1.3.node->next= NULL;

2. 出队:

2.1.front =front->next;

下面看一下实现代码:

创建链式队列

// 定义链式队列结点指针结构体
typedef struct _tag_LinkQueueNode TLinkQueueNode;
struct _tag_LinkQueueNode
{TLinkQueueNode* next;void* item;
};
// 定义链式队列结构体
typedef struct _tag_LinkQueue
{TLinkQueueNode* front;TLinkQueueNode* rear;int length;
} TLinkQueue;
// 创建队列
LinkQueue* LinkQueue_Create() // O(1)
{// 定义返回变量,并申请链式队列队头内存TLinkQueue* ret = (TLinkQueue*)malloc(sizeof(TLinkQueue));// 申请成功,参考空队列条件操作if( ret != NULL ){ret->front = NULL;ret->rear = NULL;ret->length = 0;}return ret;
}

销毁队列和清空队列

// 销毁队列
void LinkQueue_Destroy(LinkQueue* queue) // O(n)
{// 清空队列,释放内存LinkQueue_Clear(queue);free(queue);
}
// 清空队列
void LinkQueue_Clear(LinkQueue* queue) // O(n)
{// 队列不为空时,所有元素出队列while( LinkQueue_Length(queue) > 0 ){LinkQueue_Retrieve(queue);}
}

进队列

// 进队列
int LinkQueue_Append(LinkQueue* queue, void* item) // O(1)
{// 定义链式队列结构变量,并强制转换入口参数TLinkQueue* sQueue = (TLinkQueue*)queue;// 定义链式队列结点指针结构变量,并申请内存TLinkQueueNode* node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));// 合法性检查int ret = (sQueue != NULL ) && (item != NULL) && (node != NULL);// 合法性OKif( ret ){// 保存插入的元素node->item = item;// 如果当前不是空队列if( sQueue->length > 0 ){sQueue->rear->next = node;         // 队尾指针next指向新元素sQueue->rear = node;               // 将队尾指针rear指向新元素node->next = NULL;                 // 新元素next指向空指针}// 当前是空队列else{sQueue->front = node;              // 队头指针指front向新元素sQueue->rear = node;               // 将对尾指针rear指向新元素node->next = NULL;                 // 新元素next指向空指针}// 队列长度加1sQueue->length++;}// 内存申请失败,释放内存,防止内存泄漏if( !ret ){free(node);}return ret;
}

出队列

// 出队列
void* LinkQueue_Retrieve(LinkQueue* queue) // O(1)
{// 定义链式队列结构变量,并强制转换入口参数TLinkQueue* sQueue = (TLinkQueue*)queue;// 定义链式队列结点指针结构变量TLinkQueueNode* node = NULL;void* ret = NULL;// 合法性检查OKif( (sQueue != NULL) && (sQueue->length > 0) ){// 保存当前队列尾指针node = sQueue->front;            // 队列尾指针指向下一个元素sQueue->front = node->next;      // 返回当前队列元素地址ret = node->item;                // 释放当前队列元素内存free(node);                      // 队列长度减1sQueue->length--;                // 队列为空,按队列条件操作if( sQueue->length == 0 ){sQueue->front = NULL;sQueue->rear = NULL;}}return ret;
}

获取队列头指针

// 获取队列头元素
void* LinkQueue_Header(LinkQueue* queue) // O(1)
{// 定义链式队列结构变量,并强制转换入口参数TLinkQueue* sQueue = (TLinkQueue*)queue;void* ret = NULL;// 合法性检查OK,返回队列头元素地址if( (sQueue != NULL) && (sQueue->length > 0) ){ret = sQueue->front->item;}return ret;
}

获取队列长度

// 获取队列长度
int LinkQueue_Length(LinkQueue* queue) // O(1)
{// 定义链式队列结构变量,并强制转换入口参数TLinkQueue* sQueue = (TLinkQueue*)queue;int ret = -1;// 合法性检查OK,返回队列长度if( sQueue != NULL ){ret = sQueue->length;}return ret;
}

验证测试代码

#include <stdio.h>
#include <stdlib.h>
#include "LinkQueue.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char *argv[])
{LinkQueue* queue = LinkQueue_Create();int a[10] = {0};int i = 0;for(i=0; i<10; i++){a[i] = i + 1;LinkQueue_Append(queue, a + i);}printf("Header: %d\n", *(int*)LinkQueue_Header(queue));printf("Length: %d\n", LinkQueue_Length(queue));LinkQueue_Clear(queue);while( LinkQueue_Length(queue) > 0 ){printf("Retrieve: %d\n", *(int*)LinkQueue_Retrieve(queue));}LinkQueue_Destroy(queue);return 0;
}

到此我们就完成了链式队列的优化,详细代码见下方链接:

链式队列优化C实现代码

数据结构之链式队列的优化相关推荐

  1. 数据结构-队列之链式队列

    队列的链式表示称为链队列,它实际上是一个同时带有队头指针和队尾指针的单链表.头指针指向队头节点,尾指针指向队尾节点,即单链表的最后一个节点. 当q.front==NULL且q.rear==NULL时, ...

  2. 数据结构——链式队列解析(C语言版)

    摘自:数据结构学习--链式队列解析(C语言版) 作者:正弦定理 发布时间:2020-11-26 21:07:08 网址:https://blog.csdn.net/chinesekobe/articl ...

  3. 数据结构之顺序队列的优化

    顺序队列的优化 我们既然想优化顺序队列,首先得知道目前顺序队列的瓶颈在哪里,那样才能对症下药. 顺序队列的瓶颈: 1.线性表的第一个元素作为队头,线性表的最后一个元素作为队尾: 2.入队的新元素是在线 ...

  4. C++数据结构之链式结构

    链式结构 链式数据结构 typedef struct LNode {ElemType data;struct LNode *next; } LNode, *LinkList; 链队列(Link Que ...

  5. 数据结构之链式存储结构和顺序存储结构

    顺序存储结构: 定义:在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,以数据元素为单位,按数据元素在表中的次序存储. 优点: 不用为表示节点间的逻辑关系而增加额外的存储开销. 具有按元 ...

  6. 链式存储结构 php,【PHP 实现数据结构】链式队列

    什么是链式队列 队列是一种"先进先出"的存储结构,是一种特殊的线性表,于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作. 通常队列可以分为顺序队 ...

  7. 数据结构上机实践第七周项目2 - 自建算法库——链队(链式队列)

    自建算法库--链队(链式队列) 实现源代码如下: 1.liqueue.h /* copyright (t) 2016,烟台大学计算机学院 *All rights reserved. *文件工程名称:1 ...

  8. 【数据结构】链式队列的实现(C语言)

    队列的链式存储称为链式队列.链式队列就是一个特殊的单链表,对于这种特殊的单链表,它的插入和删除操作规定在单链表的不同端进行.链式队列的队首和队尾指针分别用front和rear表示. 链式队列要掌握以下 ...

  9. 数据结构 - 队列简介 及 1个简单的c语言链式队列代码实现

    1. 队列的定义 所谓队列(queue)就是一种能实现"先进先出"的一种线性存储结构. 跟栈有点类似,  例如栈只有1个出入口, 任何元素进入或者离开栈都必须经过同1个出入口(栈顶 ...

最新文章

  1. python计算特征与目标的相关性并可视化
  2. 从hotspot底层对象结构理解锁膨胀升级过程||深入jdk源码理解longadder的分段cas优化机制——分段CAS优化
  3. wifi网络结构(上)
  4. arduino向串口发送数据时掉包_[技术]清楚简单,一种串口触摸屏的开发流程和方法介绍...
  5. html tr中可以有br吗,html table tr td br 什么意思 缩写
  6. http预请求options
  7. [nodejs][html5][css3][js] 个人网站上线
  8. 生成 excel 直接用 httpServletResponse 输出
  9. php 创建任务程序命令行,PHP Yii 命令行程序以及定时任务详解
  10. 2022年2月份谷哥学术资源分享下载列表 20/20
  11. JS调用OCX控件过程
  12. 应广单片机及mini-c快速入门
  13. 品牌设计与VI设计的不同之处
  14. Transportation Research(TR)系列主编汇总
  15. 「大学必读」计算机专业学生一定要学好哪些课程?
  16. 知名学者,全职加盟C9高校!
  17. 你想象不到这些明星竟然是程序员出身
  18. Android怎么查看手机中的本地数据库
  19. R安装与卸载、RStudio安装
  20. 网页头部的声明 lang=zh和 lang=zh-cn 及 lang=zh-cmn的区别

热门文章

  1. Java 算法 能量项链
  2. pytorch测试模型时根据不同列别的概率值得到具体的分类
  3. 锐起无盘辅服务器的作用,锐起无盘特殊功用为网吧带来更多收益
  4. EMS批量为用户分配邮箱
  5. python简说(十八)导入模块
  6. 一些需要烂熟于心的代码
  7. beego2---入门
  8. Codeforces Round #380~#400 div2 总结 - updating
  9. 反射——类(Class)
  10. JAVA中集合输出的四种方式