C语言简明讲解队列的实现方法

目录
  • 前言
  • 队列的表示和实现
    • 队列的概念及结构
    • 代码实现
  • 束语

前言

大家好啊,我又双叒叕来水博客了,道路是曲折的,前途是光明的,事物是呈螺旋式上升的,事物最终的发展结果还是我们多多少少能够决定的,好啦,吹水结束,这与这篇博客的主题并没有太多联系。关于栈和队列这一板块本来是想不写(就是想偷懒),但是想了想,觉得这样不太好,关于数据结构这一块可能会有缺失,所以最终还是决定写,必须补齐这一块,恰好最近有时间写博客,所以还是写了,这篇博客将介绍队列的知识点,理解链表那一块的操作后,栈和队列的相关操作还是比较容易去理解的。

队列的表示和实现

队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First in First Out)

入队列:进行插入操作的一端称为队尾

出队列:进行删除操作的一端称为队头

敲黑板,开始摸鱼:

其实也没什么重点啦,都是一些基本的概念性东西,主要有:

1.要理解FIFO代表的意思

2.什么是队尾队头,别弄混了

队列的实现有两种方法:

数组:不适合,队头出数据需要挪动数据,一般还会出现假溢出,循环队列啥的

链表:单链表较合适,头删尾插,效率较高

当然,并不是说一定要用哪种,由于课本是以数组为例,这里以单链表为例

代码实现

还是老样子,分为三部分,直接上手代码,来,跟着我一起敲

Queue.h

#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;
 typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;
 //初始化
 void QueueInit(Queue* pq);
 //销毁
 void QueueDestory(Queue* pq);
 //队尾入
 void QueuePush(Queue* pq, QDataType x);
 //队头出
 void QueuePop(Queue* pq);
 //取队头数据
 QDataType QueueFront(Queue* pq);
 //取队尾数据
 QDataType QueuBack(Queue* pq);
 //个数
 int QueueSize(Queue* pq);
 //判断是否为空
 bool QueueEmpty(Queue* pq);

Queue.c

#include "Queue.h"
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
}
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}
//队尾入
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
}
//队头出
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	//1.一个(防止野指针)
	//2.多个
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}
QDataType QueuBack(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->tail->data;
}
int QueueSize(Queue* pq)
{
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		++size;
		cur = cur->next;
	}
	return size;
}
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head == NULL;
}

Test.c

#include "Queue.h"
void TestQueue()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
	QueueDestory(&q);
}
int main()
{
	TestQueue();
	return 0;
}

束语

关于堆栈和队列的相关操作就说到这里了,如果对你有帮助的话,那就点个赞把!

到此这篇关于C语言简明讲解队列的实现方法的文章就介绍到这了,更多相关C语言队列内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言数据结构之队列算法详解

    目录 一.前言 二.基本概念 三.顺序队列 四.链队列 五.循环队列 六.总结与提高 一.前言 队列在程序设计中经常出现,如:操作系统中的排队问题. 这篇文章主要介绍了队列的基本概念.性质,顺序.链.循环三种不同的方法实现队列,顺序和循环队列在算法中比较常用 二.基本概念    定义:队列是允许在一端插入,另一端删除的线性表 队头(front):允许删除的一端 队尾(rear):允许插入的一端 特点:先进先出 三.顺序队列 动态图: 算法讲解:  图解:入队,rear++,出队,front++

  • C语言用栈模拟实现队列问题详解

    目录 题目描述 题目链接 思路分析 代码实现 题目描述 请你仅使用两个栈实现先入先出队列.队列应当支持一般队列支持的所有操作(push.pop.peek.empty). 你只能使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的. 题目链接 用栈实现队列 思路分析 题目的意思是要用两个栈来模拟实现一个队列.仅可以用栈的基本功能实现队列的基本功能.所以需要创建两个栈.所以这两个栈st1,st2可用一个结构

  • C语言 队列的实现全解析

    目录 队列的实现 基本概念 创建结构体 初始化结构体 销毁队列结构体 入队 出队 判断队列是否为空 访问对头的值 访问队尾的值 返回队列的长度 Queue.h Queue.c Test.c “ 江天一色无纤尘,皎皎空中孤月轮. ” 队列的实现 基本概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 队列也可以数组和链表的结构实现,

  • C语言数据结构系列队列篇

    目录 一.队列(Queue) 0x00队列的概念 0x01队列的结构 二.队列的定义 0x00链式队列 0x02 接口函数 三.队列的实现 0x00队列初始化(QueueInit) 0x01销毁队列(QueueDestroy) 0x02判断队列是否为空(HeapIsEmpty) 0x03入队(QueuePush) 0x04出队(QueuePop) 0x05 返回队头数据(QueueFront) 0x06 返回队尾数据(QueueBack) 0x07 求队列大小(QueueSize) 0x08完整

  • C语言队列和应用详情

    目录 1.队列的原理 2.队列的作用 3.队列程序设计思路 4.入列 5.出列 6.掌握队列程序编写 7.队列的应用 1.队列的原理 队列原理其实就像一个管道,如果我们不断往管道里面塞乒乓球,每个乒乓球在管道里就会排列一条队形.先进去的乒乓球就会先出来,这个就是队列的先进先出的规则. 球从左边进去,进去的动作就是入列,然后进去的球在管道里排成一个队列,这个叫队列缓存,说白了就是数组,那么这里存了5个球就相当于是buff[5];这样的意思,最右边出来的1号球就是最早进去的球,出来的这个动作叫出列,

  • C语言简明讲解队列的实现方法

    目录 前言 队列的表示和实现 队列的概念及结构 代码实现 束语 前言 大家好啊,我又双叒叕来水博客了,道路是曲折的,前途是光明的,事物是呈螺旋式上升的,事物最终的发展结果还是我们多多少少能够决定的,好啦,吹水结束,这与这篇博客的主题并没有太多联系.关于栈和队列这一板块本来是想不写(就是想偷懒),但是想了想,觉得这样不太好,关于数据结构这一块可能会有缺失,所以最终还是决定写,必须补齐这一块,恰好最近有时间写博客,所以还是写了,这篇博客将介绍队列的知识点,理解链表那一块的操作后,栈和队列的相关操作还

  • C语言简明讲解操作符++和--的使用方法

    目录 一.++与--操作符的本质 二.++与-- 操作符使用分析 三.小结 一.++与--操作符的本质 ++ 和 -- 操作符对应两条汇编指令 前置 变量自增(减)1 取变量值 后置 取变量值 变量自增(减)1 下面看一段神奇的代码: #include <stdio.h> int main() { int i = 0; int r = 0; r = (i++) + (i++) + (i++); printf("i = %d\n", i); printf("r =

  • C语言简明讲解归并排序的应用

    目录 一.归并排序 1.1归并排序引入 1.2归并排序的概念 1.3归并排序的原理 1.4实例说明 1.5具体步骤说明 1.6代码实现 1.7性能分析 一.归并排序 1.1归并排序引入 对于堆排序来说,因为用到了完全二叉树的深度是(log2n+1)的特性,所以效率就比较高,但是堆结构的设计比较复杂,现在我们想要可以直接利用完全二叉树来排序的方法,这个方法就是归并排序. 1.2归并排序的概念 归并排序是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比

  • C语言简明讲解快速排序的应用

    目录 快速排序 1.1快速排序引入 1.2快速排序的基本思想 1.3快速排序的排序流程 1.4实例说明 1.5代码实现 1.6性能分析 快速排序 快速排序,说白了就是给基准数据找其正确索引位置的过程 1.1快速排序引入 希尔排序相当于直接插入排序的升级,他们属于插入排序类:堆排序相当于简单选择排序的升级,他们同属于选择排序类:而对于交换排序类的冒泡排序升级版本就是快速排序. 1.2快速排序的基本思想 通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字比另一部分记录的关键字小,则可分

  • C语言简明讲解三目运算符和逗号表达式的使用

    目录 一.三目运算符 二.逗号表达式 三.小结 一.三目运算符 三目运算符( a ? b : c)可以作为逻辑运算的载体 规则:当 a 的值为真时,返回 b 的值:否则返回 c 的值 下面看一段代码: #include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a < b ? a : b; (a < b ? a : b) = 3; printf("%d\n", a); printf(&

  • C语言简明讲解类型转换的使用与作用

    目录 一.类型之间的转换 二.强制类型转换 三.隐式类型转换 四.表达式中的隐式类型转换 五.小结 一.类型之间的转换 C语言中的数据类型可以进行转换 强制类型转换 隐式类型转换 二.强制类型转换 强制类型转换的语法 (Type)var_name; (Type)value; 强制类型转换的结果 目标类型能够容纳目标值:结果不变 目标类型不能容纳目标值:结果将产生截断 注意:不是所有的强制类型转换都能成功,当不能进行强制类型转换时,编译器将产生错误信息(比如将自定义数据类型转换成基本数据类型).

  • C语言 详细讲解#pragma的使用方法

    目录 一.#pragma 简介 二.#pragma message 三.#pragma once 四.#pragma pack 五.小结 一.#pragma 简介 #pragma 用于指示编译器完成一些特定的动作 #pragma 所定义的很多指示字是编译器特有的 #pragma 在不同的编译器间是不可移植的 预处理器将忽略它不认识的 #pragma 指令 不同的编译器可能以不同的方式解释同一条 #pragma 指令 一般用法: #pragma parameter 注:不同的 parameter

  • C语言简明讲解变量的属性

    目录 一.C语言中的变量属性 二.auto 关键字 三.register 关键字 四.static 关键字 五.extern 关键字 六.小结 一.C语言中的变量属性 C语言中的变量可以有自己的属性 在定义变量的时候可以加上“属性”关键字 "属性”关键字指明变量的特有意义 语法: property type var_name; 示例: int main() { auto char i; register int j; static long k; extern double m; return

  • C语言简明讲解单引号与双引号的使用

    目录 一.单引号和双引号 二.小贴士 三.程序实例分析1 四.程序实例分析2 五.容易混淆的代码 六.小结 一.单引号和双引号 C语言中的单引号用来表示字符字面量 C语言中的双引号用来表示字符串字面量 'a'表示字符字面量,在内存中占1个字节,'a'+1表示'a'的ASCII码加1,结果为'b' "a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果指向"a"结束符'\0' 下面看一段单引号和双引号本质的代码: #include

  • C语言简明讲解预编译的使用

    目录 小复习 1.内置符号 2.自定义符号 3.自定义宏 4.条件编译 小复习 预处理,预编译是编译的第一步. 会有三件基本的事情发生: 引入#include 去除注释 修改#define 1.内置符号 这些符号都可以直接使用: __FILE__            点c文件全名__LINE__            当前行号__DATE__            编译日期__TIME__            编译时间 举例: #include<stdio.h> int main() {

随机推荐