广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言分别实现栈和队列详解流程
  • 660
分享到

C语言分别实现栈和队列详解流程

2024-04-02 19:04:59 660人浏览 八月长安
摘要

目录什么是栈栈的结构图示栈的实现创建栈的结构体初始化栈入栈出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空栈的销毁什么是队列?队列的实现创建队列结构体初始化队列队尾入队列队头出队列

什么是栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守先进后出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈。出数据也在栈顶。

栈的结构图示

栈的实现

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。

创建栈的结构体

我们用栈来存储数据,首先需要实现一个动态增长的栈。所以我们先创建一个栈的结构体。

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;  
	int top;       //栈顶
	int capacity;  //容量
}Stack;

初始化栈

初始化栈的方式有很多种,我们可以根据不同的需求来选择。这里写一种常规的。

void StackInit(Stack* ps)
{
	assert(ps);//检测传过来的ps是否为空
	ps->a = NULL;//把a标识的这块空间先置为空
	ps->top = ps->capacity = 0;
}

入栈

一开始top为0标识栈顶的位置,所以我们要先将数据放入栈顶,在让top向后走一位。

void StackPush(Stack* ps, STDataType x)
{
	assert(ps);//检测ps是否为空

	//如果空间满了,我们需要扩容
	if (ps->capacity == ps->top)//判断空间是否满了的条件
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//指定新空间的大小
		ps->a = (STDataType*)realloc(ps->a, newCapacity*sizeof(STDataType));//进行扩容
		if (ps->a == NULL)//扩容失败
		{
			printf("realloc fail\n");
			exit(-1);//终止程序
		}
		ps->capacity = newCapacity;//让其标识新的空间的大小
	}
	ps->a[ps->top] = x;//将数据放入栈
	ps->top++;//top向后走一步
}

出栈

void StackPop(Stack* ps)
{
	assert(ps);
	if (ps->top > 0)//避免栈里面数据已经删除完了,top依旧向下减为负数
	{
		--ps->top;
	}
}

获取栈顶元素

STDataType StackTop(Stack* ps)
{
	assert(ps);
	assert(ps->top > 0);//保证下标为正
	return ps->a[ps->top - 1];//返回栈顶元素
}

获取栈中有效元素个数

int StackSize(Stack* ps)
{
	assert(ps);
	return ps->top;
}

检测栈是否为空

检测栈是否为空,如果为空返回非零结果,如果不为空则返回0.

bool StackEmpty(Stack* ps)
{
	assert(ps);
	return ps->top == 0;//如果条件成立就返回真,否则就为假(不为空)
}

栈的销毁

void StackDestroy(Stack* ps)
{
	assert(ps);
	free(ps->a);//释放开辟的这一块空间
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

什么是队列?

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

队列的实现

队列也可以用数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

创建队列结构体

我们使用链表来实现队列,我们需要创建一个存储队列信息的结构体。

typedef int QDataType;
//链式结构:表示队列
typedef struct Queuenode
{
	QDataType data;           //存储数据
	struct QueueNode* next;   //指针域
}QNode;
//队列的结构
typedef struct Queue
{
	QNode* head;//标识队头的位置
	QNode* tail;//标识队尾的位置
}Queue;

初始化队列

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;//将两个指针置为空
}

队尾入队列

让一个数据进入队列,我们只需要用链表结构来实现队列,在队尾进行尾插数据就可以了。

如果队列为空,需要单独处理一下。

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));//申请一个新的结点
	assert(newnode);//检测结点是否申请成功
	newnode->data = x;//
	newnode->next = NULL;
	if (pq->tail == NULL)//如果队列为空的情况
	{
		assert(pq->head==NULL);
		pq->tail = pq->head = newnode;
	}
	else//队列不为空的情况
	{
		pq->tail->next = newnode;//尾插一个新结点
		pq->tail = newnode;//更新尾的位置
	}
}

队头出队列

当队列为空,没有存储数据时,我们就不能够出数据。如果队列中只有一个结点,那么我们需要对其单独处理,否则就会出现错误。

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head && pq->tail);//保证队列中有数据在往下走
	if (pq->head->next == NULL)//如果队列里面只有一个数据的情况
	{
		free(pq->head);//释放队头数据
		pq->head = pq->tail = NULL;//将队列的头指针和尾指针均置为空
	}
	else
	{
		QNode* next = pq->head->next;//让next指向队头结点的下一个结点
		free(pq->head);//释放队头结点
		pq->head = next;//让head指向next结点
	}
}

获取队列头部元素

检测队列是否为空,如果不为空则直接返回队列头指针指向的元素。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);//检测队列是否为空
	return pq->head->data;//返回队列头部元素
}

获取队列尾部元素

检测队列是否为空,如果不为空则直接返回队列尾指针指向的元素。

//获取队列队尾元素
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);//检测队列是否为空
	return pq->tail->data;//返回队列尾部元素
}

获取队列中元素个数

可以对队列进行遍历,统计元素个数,如果队列比较长那么这个方法效率就比较低。如果想要效率比较高,那么我们可以在定义队列结构体的时候加上一个size变量,每往队列里面入一个数据就统计一下,那么我们需要队列中元素个数的时候就可以直接返回。

int QueueSize(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;//让cur指向队头的元素
	size_t size = 0;//定义一个无符号的size变量用来计数
	while (cur)//cur不为空则进入循环继续执行
	{
		size++;//size=size+1
		cur = cur->next;//继续向后遍历
	}
	return size;//返回有效元素个数
}

检测队列是否为空

检测队列是否为空,如果为空返回非零结果,如果非空返回0

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return (pq->head == NULL) && (pq->tail == NULL);
}

销毁队列

在使用完队列之后,我们应该对其进行销毁,防止造成内存泄漏。

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;//定义一个next指向cur的下一个结点
		free(cur);//释放cur
		cur = next;
	}
	pq->head = pq->tail = NULL;//将头尾指针均置为空
}

 

到此这篇关于C语言分别实现栈和队列详解流程的文章就介绍到这了,更多相关C语言栈和队列内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言分别实现栈和队列详解流程

本文链接: https://www.lsjlt.com/news/147018.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言分别实现栈和队列详解流程
    目录什么是栈栈的结构图示栈的实现创建栈的结构体初始化栈入栈出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空栈的销毁什么是队列?队列的实现创建队列结构体初始化队列队尾入队列队头出队列...
    99+
    2022-11-13
  • C语言栈与队列相互实现详解
    目录一、本章重点二、队列实现栈三、栈实现队列四、解题思路总结一、本章重点 用两个队列实现栈用两个栈实现队列解题思路总结 二、队列实现栈  我们有两个队列:  ...
    99+
    2022-11-13
  • C语言怎么实现栈和队列
    本文小编为大家详细介绍“C语言怎么实现栈和队列”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言怎么实现栈和队列”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是栈栈:一种特殊的线性表,其只允许在固定的一端...
    99+
    2023-06-30
  • C语言栈和队列如何实现
    这篇文章主要讲解了“C语言栈和队列如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言栈和队列如何实现”吧!一、栈与队列以及双端队列的概念1.1 栈的概念及结构栈:一种特殊的线性表,...
    99+
    2023-06-30
  • C语言用栈模拟实现队列问题详解
    目录题目描述题目链接思路分析代码实现题目描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty)。 你只能使用标准的栈操作...
    99+
    2022-11-13
  • C语言超详细讲解栈与队列实现实例
    目录1.思考-12.栈基本操作的实现2.1 初始化栈2.2 入栈2.3 出栈2.4 获取栈顶数据2.5 获取栈中有效元素个数2.6 判断栈是否为空2.7 销毁栈3.测试3.1 测试3...
    99+
    2022-11-13
  • C语言循环队列与用队列实现栈问题解析
    目录循环队列题目描述题目链接思路分析代码实现用队列实现栈题目描述题目链接思路分析代码实现循环队列 循环队列: 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并...
    99+
    2022-11-13
  • c语言数据结构之栈和队列详解(Stack&Queue)
    目录简介栈一、栈的基本概念1、栈的定义2、栈的常见基本操作二、栈的顺序存储结构1、栈的顺序存储2、顺序栈的基本算法3、共享栈(两栈共享空间)三、栈的链式存储结构1、链栈2、链栈的基本...
    99+
    2022-11-13
  • C++ 栈和队列的实现超详细解析
    目录1、栈的介绍:2、栈的常用接口实现 3、队列的介绍4、队列的常用接口实现 可算是把链表给结束了,很多小伙伴已经迫不及待想看到栈和队列了,那么它来了!相信有了顺...
    99+
    2022-11-13
  • C语言实现队列的示例详解
    目录前言一. 什么是队列二. 使用什么来实现栈三. 队列的实现3.1头文件3.2 函数的实现四.完整代码前言 前一段时间,我们试着用C语言实现了数据结构中的顺序表,单链表,双向循环链...
    99+
    2022-11-13
  • C语言详解链式队列与循环队列的实现
    目录队列的实现链式队列链式队列的定义链式队列的实现循环队列循环队列的定义循环队列的实现队列的实现 队列是一种先进先出(First in First Out)的线性表,简称FIFO。与...
    99+
    2022-11-13
  • Java使用跳转结构实现队列和栈流程详解
    目录导读队列跳转结构结点实现队列测试队列栈实现栈测试代码导读 在数据结构当中所有的数据结构都是由 连续数据结构或者跳转数据结构 单独或者拼接做成。 连续结构和跳转结构是数据结构中常见...
    99+
    2023-05-15
    Java跳转结构实现队列 Java跳转结构实现栈
  • C语言数据结构进阶之栈和队列的实现
    目录栈的实现:一、栈的概念和性质二、栈的实现思路三、栈的相关变量内存布局图四、栈的初始化和销毁五、栈的接口实现:1.入栈2.出栈3.获取栈顶的数据4.获取栈的元素个数5.判断栈是否为...
    99+
    2022-11-12
  • C语言怎么利用栈和队列实现回文检测功能
    本文小编为大家详细介绍“C语言怎么利用栈和队列实现回文检测功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言怎么利用栈和队列实现回文检测功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。具体代码如下:#i...
    99+
    2023-06-16
  • C语言超详细讲解队列的实现及代码
    目录前言队列的概念队列的结构队列的应用场景队列的实现创建队列结构队列初始化  队列销毁  入队列  出队列  队列判空  获取队列元...
    99+
    2022-11-13
  • Python和C语言利用栈分别实现进制转换
    目录问题描述C语言实现Python实现问题描述 利用栈的数据结构实现将十进制数转换成二进制数 C语言实现 顺序表的存储结构实现栈 代码: #include <stdlib.h&...
    99+
    2022-11-11
  • C语言数据结构与算法之队列的实现详解
    目录队列的概念及结构队列的实现Queue.hQueue.cTest.c队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FI...
    99+
    2022-11-13
    C语言数据结构 队列 C语言 队列实现 C语言 队列
  • C语言扫雷详细代码分步实现流程
    目录一,创建菜单二,创建游戏内容1.场景创建和初始化2.场景打印3.埋雷4.排雷完整代码1.game.h2.game.c3.test.c还是说一下:发的这些小游戏都是第一个版本,之后...
    99+
    2022-11-13
  • 详解用C语言实现三子棋游戏流程
    目录三子棋游戏简介一、分析及实现1.棋盘2.落子3.判断输赢二、程序演示三、完整代码1.main.c2.game.c3.game.h总结三子棋游戏简介 这是一个简单的三子棋小游戏,...
    99+
    2022-11-12
  • C语言 小游戏打砖块实现流程详解
    始祖是美国英宝格公司(en:Atari Games,ja:アタリ (ゲーム))于1976年推出的街机游戏“Breakout”(en:Breakout),由该公司在1972年发行的“...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作