数据结构 - 链队列的实行(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 ...
随机推荐
- [Unit Testing] Mock an HTTP request using Nock while unit testing
When testing functions that make HTTP requests, it's not preferable for those requests to actually r ...
- vi下对齐代码的操作
时不时会用到,但easy忘,在这里记录一下 1. ctrl + v (选中块) 2. ctrl + f (向前) 或 ctrl +v (向后) 3. 按"=", 把选中的代码对齐
- 实习生面试相关-b
面试要准备什么 有一位小伙伴面试阿里被拒后,面试官给出了这样的评价:“……计算机基础,以及编程基础能力上都有所欠缺……”.但这种笼统的回答并非是我们希望的答案,所谓的基础到底指的是什么? 作为一名 i ...
- IE9版本号下面ajax 跨域问题解决
ajax跨域请求数据在谷歌火狐我本地IE11都是没问题的. 让測试就发现问题了,IE8下请求不到数据.然后我查看一下自己写的js看有没有不兼容问题.但是都没有啊.为什么就请求不到呢. 我把ajax的e ...
- 在CentOS上把MySQL从5.5升级到5.6
在CentOS上把MySQL从5.5升级到5.6 摘要:本文记录了在CentOS 6.3上,把MySQL从5.5.28升级到5.6.19的过程. 1. 概述 在我做的一个项目中,最近我对生产服务器上的 ...
- Java基础学习之final和多态及类型转换
finalkeyword: finalkeyword是终于的意思,能够修饰类,成员变量,成员方法. • 修饰类,类不能被继承 • 修饰变量,变量就变成了常量,仅仅能被赋值一次. • ...
- SQL语句--常用
一.基础 1.说明:创建数据库CREATE DATABASE database-name 2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备 ...
- YTU 2414: C语言习题 字符串排序
2414: C语言习题 字符串排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 656 解决: 305 题目描述 输入n个字符串,将它们按字母由小到大的顺序排列并输出.编写三个函数实 ...
- android NDK 使用(多个)静态库生成动态库
android NDK 使用(多个)静态库生成动态库. 1.编写Android.mk文件:如下两种方式都可以,用于NDK编译工具生成的两个.a文件来生成最终的libtwolib-second.so动态 ...
- create database 默认utf-8
CREATE DATABASE IF NOT EXISTS dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 这是sql语句 CREATE TA ...