文章目录

  • 定义
  • 链队列 VS 循环队列
  • 链队列代码实现( C 、Java )

定义

队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而异,我们把它简称为链队列

链队列 VS 循环队列

时间角度
它们的基本操作都是常数时间,为 O[1] ,不过循环队列是事先申请好空间,使用期间不释放
对于链队列,每次申请和释放节点也会存在一点儿时间开销

空间角度
循环队列必须有一个固定的长度,所以有了存储元素个数和空间浪费的问题。而链队列更加灵活。

汇总
在可以确定队列长度最大值得情况下,建议使用循环队列,否则使用链队列。

链队列代码实现( C 、Java )

C 语言

#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "time.h"#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */typedef int Status; typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */typedef struct QNode    /* 结点结构 */
{QElemType data;struct QNode *next;
}QNode,*QueuePtr;typedef struct          /* 队列的链表结构 */
{QueuePtr front,rear; /* 队头、队尾指针 */
}LinkQueue;Status visit(QElemType c)
{printf("%d ",c);return OK;
}/* 构造一个空队列Q */
Status InitQueue(LinkQueue *Q)
{ Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));if(!Q->front)exit(OVERFLOW);Q->front->next=NULL;return OK;
}/* 销毁队列Q */
Status DestroyQueue(LinkQueue *Q)
{while(Q->front){Q->rear=Q->front->next;free(Q->front);Q->front=Q->rear;}return OK;
}/* 将Q清为空队列 */
Status ClearQueue(LinkQueue *Q)
{QueuePtr p,q;Q->rear=Q->front;p=Q->front->next;Q->front->next=NULL;while(p){q=p;p=p->next;free(q);}return OK;
}/* 若Q为空队列,则返回TRUE,否则返回FALSE */
Status QueueEmpty(LinkQueue Q)
{ if(Q.front==Q.rear)return TRUE;elsereturn FALSE;
}/* 求队列的长度 */
int QueueLength(LinkQueue Q)
{ int i=0;QueuePtr p;p=Q.front;while(Q.rear!=p){i++;p=p->next;}return i;
}/* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */
Status GetHead(LinkQueue Q,QElemType *e)
{ QueuePtr p;if(Q.front==Q.rear)return ERROR;p=Q.front->next;*e=p->data;return OK;
}/* 插入元素e为Q的新的队尾元素 */
Status EnQueue(LinkQueue *Q,QElemType e)
{ QueuePtr s=(QueuePtr)malloc(sizeof(QNode));if(!s) /* 存储分配失败 */exit(OVERFLOW);s->data=e;s->next=NULL;Q->rear->next=s;    /* 把拥有元素e的新结点s赋值给原队尾结点的后继,见图中① */Q->rear=s;      /* 把当前的s设置为队尾结点,rear指向s,见图中② */return OK;
}/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */
Status DeQueue(LinkQueue *Q,QElemType *e)
{QueuePtr p;if(Q->front==Q->rear)return ERROR;p=Q->front->next;       /* 将欲删除的队头结点暂存给p,见图中① */*e=p->data;             /* 将欲删除的队头结点的值赋值给e */Q->front->next=p->next;/* 将原队头结点的后继p->next赋值给头结点后继,见图中② */if(Q->rear==p)      /* 若队头就是队尾,则删除后将rear指向头结点,见图中③ */Q->rear=Q->front;free(p);return OK;
}/* 从队头到队尾依次对队列Q中每个元素输出 */
Status QueueTraverse(LinkQueue Q)
{QueuePtr p;p=Q.front->next;while(p){visit(p->data);p=p->next;}printf("\n");return OK;
}int main()
{int i;QElemType d;LinkQueue q;i=InitQueue(&q);if(i)printf("成功地构造了一个空队列!\n");printf("是否空队列?%d(1:空 0:否)  ",QueueEmpty(q));printf("队列的长度为%d\n",QueueLength(q));EnQueue(&q,-5);EnQueue(&q,5);EnQueue(&q,10);printf("插入3个元素(-5,5,10)后,队列的长度为%d\n",QueueLength(q));printf("是否空队列?%d(1:空 0:否)  ",QueueEmpty(q));printf("队列的元素依次为:");QueueTraverse(q);i=GetHead(q,&d);if(i==OK)printf("队头元素是:%d\n",d);DeQueue(&q,&d);printf("删除了队头元素%d\n",d);i=GetHead(q,&d);if(i==OK)printf("新的队头元素是:%d\n",d);ClearQueue(&q);printf("清空队列后,q.front=%u q.rear=%u q.front->next=%u\n",q.front,q.rear,q.front->next);DestroyQueue(&q);printf("销毁队列后,q.front=%u q.rear=%u\n",q.front, q.rear);return 0;
}

Java 语言

package com.example.stack;/* 链队列结构 * 备注:头结点front.data不存储元素* */
public class LinkQueue<T> {@SuppressWarnings("hiding")class Node<T> {protected Node<T> next;protected T data;public Node(T data){this.data = data;}}/* 队头、队尾指针 */public Node<T> front;/*链栈长度 */public Node<T> rear;/* 构造一个空队列Q */int initQueue(){this.front = new Node<T>(null);this.rear = new Node<T>(null);return 1;}/** 销毁队列 VS 清空队列 ? * 销毁队列:队列的结构都不存在了* 清空队列:有效结点清除了,但队头队尾还在,队列结构还在* 在 Java 无法做到清除结构亦或者构建的元素,顾两方法都一致* 备注;也许以后的 Java 可以做到,或没有必要*//* 销毁队列Q */int destroyQueue(){Node<T> tempNode = this.front.next;while(tempNode.data != null){tempNode.data = null;tempNode = tempNode.next;this.front.next = tempNode;}return 1;}/* 将Q清空队列 */int clearQueue(){Node<T> tempNode = this.front.next;while(tempNode.data != null){tempNode.data = null;tempNode = tempNode.next;this.front.next = tempNode;}return 1;}/* 若Q为空队列,则返回TRUE,否则返回FALSE */boolean queueEmpty(){if(this.front.data == null && this.rear.data == null)return true;elsereturn false;}/* 求队列的长度 * 遗留:Java 中New的两个新的引用对象 a 和 b,在进行 = 号表达时,无法判断它们彼此的地址是否相等?* 如本题中的 front 与 rear,无法与 C 语言中的一致,进行指针的比较* */int queueLength(){int i = 0;if(this.front.data == null && this.rear.data == null)return i;else{i = 0;this.front = this.front.next;while(this.front.data != null){i++;this.front = this.front.next;}}return i;}/* 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR */T getHead(){if(this.front.data == null && this.rear.data == null)throw new NullPointerException("为空队列!");return this.front.next.data;}/* 插入元素e为Q的新的队尾元素 */int enQueue(T elem){Node<T> tempNode = new Node<T>(elem);if(this.queueLength() == 0){this.rear=tempNode;this.rear.next = this.front;this.front.next = this.rear;}else{this.rear.next = tempNode;this.rear = tempNode;this.rear.next = this.front;}return 1;}/* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */T deQueue(){if(this.front.data == null && this.rear.data == null)throw new NullPointerException("为空队列!");T elem = this.front.next.data;//待删除元素赋予空值this.front.next.data =null;this.front.next = this.front.next.next;return elem;}/* 从队头到队尾依次对队列Q中每个元素输出 */void queueTraverse(){Node<T> tempNode = this.front.next;while(tempNode.data != null){System.out.println(tempNode.data);tempNode = tempNode.next;}}public static void main(String[] args){LinkQueue<Integer> q = new LinkQueue<Integer>();q.initQueue();System.out.println("是否空队列?%d(1:空 0:否)  "+q.queueEmpty());System.out.println("队列的长度为%d\n"+q.queueLength());q.enQueue(-5);q.enQueue(5);q.enQueue(10);System.out.println("插入3个元素(-5,5,10)后,队列的长度为%d\n"+q.queueLength());System.out.println("是否空队列?%d(1:空 0:否)  "+q.queueEmpty());System.out.println("队列的元素依次为:");q.queueTraverse();System.out.println("队头元素是:%d\n"+q.getHead());System.out.println("删除了队头元素%d\n"+q.deQueue());System.out.println("新的队头元素是:%d\n"+q.getHead());q.clearQueue();System.out.println("清空队列后,q.front="+q.front.data+" q.rear="+q.rear.data+" q.front->next="+q.front.next.data);//q.destroyQueue();//System.out.println("销毁队列后,q.front=%u q.rear=%u\n"+q.front.data+"==========="+q.rear.data);}
}

大话数据结构系列之链队列结构(十二)相关推荐

  1. 大话数据结构 第七章 图(二) 最小生成树、最短路径、拓扑排序、关键路径算法

    大话数据结构 第七章 图(二) 最小生成树.最短路径.拓扑排序.关键路径算法 最小生成树 定义 Prim算法 Kruskal算法 最短路径 Dijkstra算法 Floyd算法 拓扑排序 AOV网 拓 ...

  2. 大话数据结构-栈与队列

    文章知识点来至于大话数据结构里边章节知识, 这篇主要介绍栈与队列在计算机中存储形式, 以及在某些算法领域中对栈和队列的相关应用.章节最后介绍了著名的逆波兰表达式, 以及通过算法来实现该表达式的运算过程 ...

  3. 大话数据结构—栈与队列

    栈 一.栈的定义 栈是(stack)是限定尽在表尾进行插入和删除操作的线性表. 栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构. 二.进栈出栈变化形式 注意: 并不是 ...

  4. 【Java数据结构与算法】第十二章 哈夫曼树和哈夫曼编码

    第十二章 哈夫曼树和哈夫曼编码 文章目录 第十二章 哈夫曼树和哈夫曼编码 一.哈夫曼树 1.基本术语 2.构建思路 3.代码实现 三.哈夫曼编码 1.引入 2.介绍 3.代码实现哈夫曼编码综合案例 一 ...

  5. 大话数据结构系列之栈的实际应用(十)

    文章目录 斐波那契函数推导( Java.C ) 使用栈来实现四则运算( Java.C ) 栈与递归的关系 "递归"与"迭代"的选择性讨论 诗词即兴环节 斐波那契 ...

  6. 大话数据结构11:队列 链表结构

    基础介绍 用链表实现的队列 代码 #include "stdio.h" #include "stdlib.h" #include "io.h" ...

  7. 侠客岛--多线程系列之线程池(十二)

    文章目录 线程池原理 一.为什么要使用线程池 二.线程池的原理 1. ThreadPoolExecutor提供的构造方法 1.1 构造方法 1.2 构造方法参数 2. ThreadPoolExecut ...

  8. 数据结构与算法-基础(十二)B 树

    摘要 B 树是一种平衡的多路搜索树,在添加.删除和搜索等一些操作上和二叉搜索树是同样的逻辑,除此之外 4 阶 B 树在结构上和红黑树也是相似的.所以了解 B 树,可以更好的切入学习红黑树. 红黑树是自 ...

  9. 雷达系列论文翻译(十二):Cartographer系列(三)

    Real-Time Loop Closure in 2D LIDAR SLAM 摘要 便携式激光测距仪,又称激光雷达,同时定位和建图(SLAM)是一种有效的获取竣工平面图的方法.实时生成和可视化楼层平 ...

最新文章

  1. boseqc35能不能连电脑_连win7都用不了?轻量级LXLE系统,只要10分钟,旧电脑也能运行如飞!...
  2. RobotFramework操作API
  3. vertical-align属性详解
  4. php 前端模板 yii,php – Yii2高级模板:添加独立网页
  5. 读书笔记之inside JVM(4)
  6. 鸿蒙会取代emui,华为称自家手机运行鸿蒙系统正在推进 未来会取代安卓吗?
  7. python元组_Python元组
  8. java毕业设计——基于java+JSP+MySQL的网上订餐管理系统设计与实现(毕业论文+程序源码)——网上订餐管理系统
  9. python3将网页保存为pdf
  10. 正则表达式提取HTML中IMG标签的SRC地址
  11. Visio里如何画树状图?
  12. 可编辑!热门动态表情包!
  13. Element-ui组ICON图标
  14. 支付宝当面付实现跳转到指定网页唤起支付
  15. 阿哈c语言教程pdf,C++教程-完整版.pdf
  16. Magento订单打印(pdf格式) 转:鹏程万里
  17. 千兆网卡和普通网卡有什么区别?如何判断?
  18. wow服务器信息,魔兽世界2.4服务器最新消息和消息汇总
  19. 解决问题:Class JavaLaunchHelper is implemented in both
  20. 独立产品灵感周刊 DecoHack #027 - 今天的天气适合穿短裤

热门文章

  1. Directx+CEGUI把界面集成到游戏中,支持全屏方式(c++)
  2. 2018年 10月份开始执行的最新税率表 2019年1月 小孩住房贷款等怎么扣
  3. TokenRise的见茶卸甲@一杯严选 六道一辉探访“茶人的栖息地@世科坊”
  4. 频谱、频谱密度、能量谱密度、功率谱密度
  5. 个域名最多能对应几个IP地址?,一个IP地址可以绑定几个域名?
  6. <网络概述>——《计算机网络》
  7. 算法设计与分析-TSP六种方法-贪心算法(最近邻点、最短链接)、蛮力法、动态规划法、回溯法、分支限界法、模拟退火
  8. 如何在html中在线预览pdf文件?
  9. (4)数据分析-正态性检验与方差齐性检验
  10. Vultr(云服务器)安装GUI图形化界面(已解决)