数据结构 - 链队列的实行(C语言)
一、什么是链队列?
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向尾结点,如下图所示:

空队列时,front和rear都指向头结点,如下图所示。

链队列的结构为:
typedef int QElemType; /* QElemType类型根据实际情况而定,这里假设为int */
/* 结点结构 */
typedef struct QNode
{
ElemType data;
struct QNode *next;
}QNode;
/* 队列的链表结构 */
typedef struct
{
QNode *front; // 队头指针
QNode *rear; // 队尾指针
}LinkQueue;
二、基本操作
2.1 初始化操作
实现代码如下:
// 初始化链队列操作
Status initQueue(LinkQueue *Q)
{
Q->front = Q->rear = (Node *)malloc(sizeof(Node));
if (!Q->front)
return FALSE;
Q->front->next = NULL;
return TRUE;
}
2.1 入队操作
人队操作时,其实就是在链表尾部插入结点,如下图所示:

实现代码如下:
// 入队操作
Status enQueue(LinkQueue *Q, ElemType e)
{
Node *s = (Node *)malloc(sizeof(Node));
if (!s)
return FALSE;
s->data = e;
s->next = NULL;
Q->rear->next = s; // 把拥有元素e的新结点s赋值给原队尾结点的后继
Q->rear = s; // 把当前的s设置为队尾结点,rear指向s
return TRUE;
}
2.3 出队操作
出队操作时,就是头结点的后继结点出队,将头结点的后继改为它后面的结点,若链表除头结点外只剩一个元素时,则需将rear指向头结点,如下图所示:

实现代码如下:
// 出队操作
Status deQueue(LinkQueue *Q, ElemType *e)
{
Node *p;
if (Q->front == Q->rear)
return FALSE;
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 TRUE;
}
2.4 遍历操作
实现代码如下:
// 遍历队列操作
Status tarverseQueue(const LinkQueue Q)
{
Node *p;
p = Q.front->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return TRUE;
}
三、完整程序
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int ElemType; /* ElemType类型根据实际情况而定,这里假设为int */
/* 结点结构 */
typedef struct Node
{
ElemType data;
struct Node *next;
}Node;
/* 队列的链表结构 */
typedef struct
{
Node *front; // 队头指针
Node *rear; // 队尾指针
}LinkQueue;
Status initQueue(LinkQueue *Q); // 初始化链队列操作
Status enQueue(LinkQueue *Q, ElemType e); // 入队操作
Status deQueue(LinkQueue *Q, ElemType *e); // 出队操作
Status tarverseQueue(const LinkQueue Q); // 遍历队列操作
Status destroyQueue(LinkQueue *Q); // 销毁队列操作
Status clearQueue(LinkQueue *Q); // 清空队列操作
Status isEmpty(const LinkQueue Q); // 判断是否为空队列
Status getHead(const LinkQueue Q, ElemType *e); // 获得队头元素
int getLength(const LinkQueue Q); // 获得队列的长度
// 初始化链队列操作
Status initQueue(LinkQueue *Q)
{
Q->front = Q->rear = (Node *)malloc(sizeof(Node));
if (!Q->front)
return FALSE;
Q->front->next = NULL;
return TRUE;
}
// 入队操作
Status enQueue(LinkQueue *Q, ElemType e)
{
Node *s = (Node *)malloc(sizeof(Node));
if (!s)
return FALSE;
s->data = e;
s->next = NULL;
Q->rear->next = s; // 把拥有元素e的新结点s赋值给原队尾结点的后继,见图中①
Q->rear = s; // 把当前的s设置为队尾结点,rear指向s,见图中②
return TRUE;
}
// 出队操作
Status deQueue(LinkQueue *Q, ElemType *e)
{
Node *p;
if (Q->front == Q->rear)
return FALSE;
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 TRUE;
}
// 遍历队列操作
Status tarverseQueue(const LinkQueue Q)
{
Node *p;
p = Q.front->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
return TRUE;
}
// 销毁队列操作
Status destroyQueue(LinkQueue *Q)
{
while (Q->front)
{
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return TRUE;
}
// 清空队列操作
Status clearQueue(LinkQueue *Q)
{
Node *p;
Node *q;
Q->rear = Q->front;
p = Q->front->next;
Q->front->next = NULL;
while (p)
{
q = p;
p = p->next;
free(q);
}
return TRUE;
}
// 判断是否为空队列
Status isEmpty(const LinkQueue Q)
{
return Q.front == Q.rear ? TRUE : FALSE;
}
// 获得队头元素
Status getHead(const LinkQueue Q, ElemType *e)
{
Node *p;
if (Q.front == Q.rear)
return FALSE;
p = Q.front->next;
*e = p->data;
return TRUE;
}
// 获得队列的长度
int getLength(const LinkQueue Q)
{
int i = 0;
Node *p;
p = Q.front;
while (Q.rear != p)
{
i++;
p = p->next;
}
return i;
}
int main()
{
LinkQueue Q;
// 初始化队列
initQueue(&Q);
// 入队操作
for (int i = 0; i < 4; i++)
enQueue(&Q, i);
printf("入队操作(0、1、2、3)! \n\n");
// 出队操作
ElemType d;
deQueue(&Q, &d);
printf("删除的元素是%d \n\n", d);
// 遍历队列
printf("遍历队列: ");
tarverseQueue(Q);
printf("\n");
// 判断是否为空队列
printf("现在队列空否? %u (1:空 0:否)\n\n", isEmpty(Q));
// 获得队列的长度
printf("队列长度为: %d \n\n", getLength(Q));
// 获得队头元素
getHead(Q, &d);
printf("队头元素是%d \n\n", d);
return 0;
}
输出结果如下图所示:

参考:
《大话数据结构 - 第4章》 栈与队列
数据结构 - 链队列的实行(C语言)的更多相关文章
- 数据结构——链队列(linked queue)
/* linkedQueue.c */ /* 链队列 */ #include <stdio.h> #include <stdlib.h> #include <stdboo ...
- 数据结构 - 链栈的实行(C语言)
数据结构-链栈的实现 1 链栈的定义 现在来看看栈的链式存储结构,简称为链栈. 想想看栈只是栈顶来做插入和删除操作,栈顶放在链表的头部还是尾部呢?由于单链表有头指针,而栈顶指针也是必须的,那干吗不让它 ...
- 数据结构 - 顺序队列的实行(C语言)
数据结构-顺序队列的实现 1 顺序队列的定义 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式.我们先来看队列的顺序存储结构. 队列的顺序储存结构:用数组存储队列,为了避 ...
- C语言数据结构-循环队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
1.数据结构-循环队列的实现-C语言 #define MAXSIZE 100 //循环队列的存储结构 typedef struct { int* base; //基地址 int _front; //头 ...
- C语言数据结构-链式队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
1.数据结构-链式队列的实现-C语言 typedef struct QNode { int data; struct QNode *next; }QNode,*QueuePtr; typedef st ...
- 【Java】 大话数据结构(7) 循环队列和链队列
本文根据<大话数据结构>一书,实现了Java版的循环队列.链队列. 队列:只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 1.循环队列 队列的顺序储存结构:用数组存储队列,引入 ...
- javascript实现数据结构与算法系列:队列 -- 链队列和循环队列实现及示例
1 队列的基本概念 队列(Queue):也是运算受限的线性表.是一种先进先出(First In First Out ,简称FIFO)的线性表.只允许在表的一端进行插入,而在另一端进行删除. 队首(fr ...
- java与数据结构(8)---java实现链队列
链队列 实际上就是单链表,只是规定了删除在队头进行,添加在队尾进行. 链队列代码结构 package list.queue; public interface Queuable<T>; p ...
- C语言实现链队列的初始化&进队&出队
/*链表实现队列的一系列操作*/ #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 typed ...
随机推荐
- 【转】面向切面编程-AOP,挺有用的
原文:http://blog.csdn.net/yangzhihello/article/details/40377399 下面的代码有点问题, ins[methodName] = function( ...
- hdu1181 dfs搜索之变形课
原题地址 这道题数据据说比較水,除了第一组数据是Yes以外.其余都是No.非常多人抓住这点就水过了.当然了,我认为那样过了也没什么意思.刷oj刷的是质量不是数量. 这道题从题目上来看是个不错的 搜索题 ...
- Linux下进程信息的深入分析
这里我们主要介绍进程的状态,进程的状态可以通过/proc/PID/status来查看,也可以通过/proc/PID/stat来查看. 如果说到工具大家用的最多的ps也可以看到进程的信息.这里我们通过/ ...
- 【剑指Offer面试题】 九度OJ1517:链表中倒数第k个结点
鲁棒性是指程序可以推断输入是否符合规范要求,并对不和要求的输入予以 合理的处理. 题目链接地址: http://ac.jobdu.com/problem.php?pid=1517 题目1517:链表中 ...
- 一个IM开源项目LiteTalk
http://blog.csdn.net/visualwind/article/details/6086631 http://blog.sina.com.cn/s/blog_54b5ea250101n ...
- Linux上ln命令详细说明及软链接和硬链接的区别
硬链接(hard link) UNIX文件系统提供了一种将不同文件链接至同一个文件的机制,我们称这种机制为链接.它可以使得单个程序对同一文件使用不同的名字.这样的好处是文件系 统只存在一个文件的副本, ...
- os 2大功能
支撑功能 中断管理 时钟管理 原语操作 primitive 资源管理功能 进程管理 存储器管理 设备管理
- js加减乘除丢失精度
js加减乘除(学了那么久现在才注意到汗==!) /** ** 除法函数,用来得到精确的除法结果 ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显.这个函数返回较为精 ...
- mac系统下设置eclipse的补全快捷键方法
eclispe Word Completion 的默认快捷键是Alt+/eclipse Content Assist 的默认快捷键是Ctrl+Space在使用中发现Word Completion经常导 ...
- luogu 3960 列队
noip2017 D2T3 列队 某zz选手当时直接放弃了写了50还写错了 题目大意: 有一个n行m列的方阵,第i行j列的点编号为(i-1)m+j 每次把第x行y列的点拿出来,然后把这一行它之后的点都 ...