【数据结构】第五讲:栈和队列

 个人主页:深情秋刀鱼@-CSDN博客

数据结构专栏:数据结构与算法

源码获取:数据结构: 上传我写的关于数据结构的代码 (gitee.com)

目录

一、栈

1.栈的定义

 2.栈的实现

 a.栈结构的定义

b.初始化

c.扩容

d.入栈

e.出栈

f.打印

g.取栈顶元素

 h.判空

i.获取栈中的元素个数

j.销毁

二、队列 

1.队列的定义

2.队列的实现

a.队列结构的定义

b.初始化

c.创建节点

d.入队

e.出队

f.队中的元素个数

g.队列判空

h.队列打印

i.取队头元素

 j.取队尾元素

 k.销毁


一、栈

1.栈的定义

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

 2.栈的实现

        栈的实现一般可以用数组和链表实现,一般情况下用数组实现更为合适,因为在数组尾部进行插入和删除操作的代价较小。

 a.栈结构的定义

typedef int STDataType;

//定义栈结构(数组)
typedef struct Stack
{
	STDataType* a;  //数组栈
	int top;		//栈顶
	int capacity;   //容量
}Stack;

b.初始化

void STInit(Stack* pst)
{
	assert(pst);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = -1;
}

c.扩容

void STExpan(Stack* pst)
{
	if (pst->top + 1 == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail!");
			return;
		}
		pst->a = tmp;
		pst->capacity = newcapacity;
	}
}

        在对栈中的数组进行扩容时,需要注意其他参数如容量(capacity)的变化,在一开始我们将capacity初始化为0,所以在这里要对capacity进行判空。

d.入栈

void STPush(Stack* pst, STDataType x)
{
	assert(pst);
	STExpan(pst);
	pst->top++;
	pst->a[pst->top] = x;
}

e.出栈

void STPop(Stack* pst)
{
	assert(pst && pst->top > -1);
	pst->top--;
}

f.打印

void STPrint(Stack* pst)
{
	while (!STEmpty(pst))
	{
		printf("%d ", STTop(pst));
		STPop(pst);
	}
}

g.取栈顶元素

STDataType STTop(Stack* pst)
{
	assert(pst && pst->top > -1);
	return pst->a[pst->top];
}

 h.判空

bool STEmpty(Stack* pst)
{
	assert(pst);
	return pst->top == -1;
}

i.获取栈中的元素个数

int STSize(Stack* pst)
{
	assert(pst);
	return pst->top + 1;
}

j.销毁

void STDestroy(Stack* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

二、队列 

1.队列的定义

        队列是只允许在一端进行插入,另一端进行删除数据操作的线性表。队列中的数据元素遵循先进先出FIFO(First in First out)的原则。进行插入操作的一端称为队尾,进行删除操作的一端成为队头

2.队列的实现

         队列可以用数组和链表实现,使用链表的结构更优,因为如果使用数组,在执行出队列的操作时效率会比较低。

a.队列结构的定义

typedef int QDataType;

//定义队列节点
typedef struct QueueNode
{
	struct QueueNode* next;		//后继指针
	QDataType val;			//数值
}QNode;

//队列指针
typedef struct Queue
{
	QNode* head;			//队头指针
	QNode* tail;			//队尾指针
	int size;				//队列中的元素
}Queue;

        为了简化实现函数时参数的传递,我们额外定义一个包含一个头节点和尾节点的结构体,其中头节点和尾节点应分别指向一个链表的头和尾。

b.初始化

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
	pq->size = 0;
}

c.创建节点

QNode* QueueBuyNode(QDataType x)
{
	QNode* newNode = (QNode*)malloc(sizeof(QNode));
	if (newNode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newNode->next = NULL;
	newNode->val = x;
	return newNode;
}

d.入队

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* node = QueueBuyNode(x);
	if (pq->head == NULL)	// 判空
	{
		pq->head = pq->tail = node;
		pq->size++;
	}
	else
	{
		pq->tail->next = node;
		pq->tail = pq->tail->next;
		pq->size++;
	}
}

e.出队

void QueuePop(Queue* pq)
{
	assert(pq && pq->head);
	QNode* phead = pq->head;
	pq->head = pq->head->next;
	free(phead);
	phead = NULL;
	if (pq->head == NULL)				 //队列为空	
		pq->tail = NULL;
	pq->size--;
}

f.队中的元素个数

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

g.队列判空

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->size == 0;
}

h.队列打印

void QueuePrint(Queue* pq)
{
	assert(pq);
	if (pq->size == NULL)
	{
		printf("NULL\n");
		return;
	}
	QNode* pcur = pq->head;
	while (pcur)
	{
		printf("%d ", pcur->val);
		pcur = pcur->next;
	}
	printf("\n");
}

i.取队头元素

QDataType QueueFront(Queue* pq)
{
	assert(pq && pq->head);
	return pq->head->val;
}

 j.取队尾元素

QDataType QueueBack(Queue* pq)
{
	assert(pq && pq->tail);
	return pq->tail->val;
}

 k.销毁

void QueueDestroy(Queue* pq)
{
	assert(pq);
	QNode* pcur = pq->head;
	while (pcur)
	{
		QNode* pnext = pcur->next;
		free(pcur);
		pcur = pcur->next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/612979.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解双曲型非线性方程的Harden-Yee算法(TVD格式)

解双曲型非线性方程的TVD格式Harden-Yee算法 算法如图 该算法可以很好地压制震荡,并且耗散很小。具体算法如图所示 import matplotlib import math matplotlib.use(TkAgg) import numpy as np import matplotlib.pyplot as plt def Phiy(yy,epsi):#phi(y)if a…

matlab-贪婪算法寻找最小覆盖

文章目录 一、最小结点集是什么二、贪婪算法实现查找最小结点集代码结果 一、最小结点集是什么 最小覆盖集(也称为最小点覆盖集)是图论中的一个重要概念,指的是一个节点子集,使得图中的每一条边都与这个子集中的至少一个节点关联…

本地安装llama-3大模型,无需联网即可跟AI大模型聊天

Llama 3 模型简介 Llama 3是Meta AI开源的第三代Llama系列模型,其新的 8B 和 70B 参数 Llama 3 模型在Llama 2的基础上,实现了更大性能的提升。由于预训练和训练后的技术改进,其Llama 3模型是当今 8B 和 70B 参数规模的最佳模型。Llama 3模型的改进大大降低了错误拒绝率,改…

机器人系统ros2-开发实践09-如何向 tf2 添加额外的坐标帧位置(Python)

在之前的教程中,我们通过编写tf2 广播器和tf2 监听器重新创建了乌龟演示。本教程将教您如何向转换树添加额外的固定和动态框架。事实上,在 tf2 中添加框架与创建 tf2 广播器非常相似,但此示例将向您展示 tf2 的一些附加功能。 对于许多与转换…

音频数字信号I2S一些知识理解

(1)I2S单向基本传输需要几根线传输音频信号? 3根线 LRCK SCLK(也叫BLK) DATA(单向) (2)如何理解I2S MASTER或者SLAVE的模式? codec的i2s作为slave mode,LRCK和SCLK来自于soc主控端,codec端自动检测MCLK和LRCK codec的i2s作为master mode,codec通过MCLK LRCLKDIV…

Java String转JSONObject时保持字段顺序不变

Java String转JSONObject时保持字段顺序不变 问题背景解决方案 问题背景 在业务接口开发过程中,有一个新增接口,需要支持批量新增数据,这时入参就需要用到 json 格式数据,且包含 list 集合,比如这样的数据格式&#x…

计算机视觉中的计算几何

计算几何领域出现于 20 世纪 70 年代,研究解决几何问题的数据结构和算法。这尤其包括确定图像内的拓扑结构,或者实际上是更高维的表示,例如点邻域,这可以帮助从数字图像数据等中导出几何意义[1]。 计算机视觉主要涉及静态或动态图…

Redis数据结构-Dict

1.3 Redis数据结构-Dict 我们知道Redis是一个键值型(Key-Value Pair)的数据库,我们可以根据键实现快速的增删改查。而键与值的映射关系正是通过Dict来实现的。 Dict由三部分组成,分别是:哈希表(DictHashTa…

[muduo网络库]——muduo库三大核心组件之 Poller/EpollPoller类(剖析muduo网络库核心部分、设计思想)

接着上文,[muduo网络库]——muduo库三大核心组件之Channel类(剖析muduo网络库核心部分、设计思想),本章我们来学习muduo网络库中第二大核心组件Poller/EpollPoller类。 先回顾一下三大核心组件之间的关系。 接着我们进入正题。 P…

什么是Meme币?——区块链技术的加密货币

Meme代币是一种基于区块链技术的加密货币,旨在为用户提供一种简单、有趣且易于传播的方式来进行数字资产交易和投资。Meme代币通常与特定的主题或故事相关联,通过社交媒体等渠道进行传播和推广,吸引更多的用户参与并增加其价值。 Meme代币的…

提升SEO排名!SSL证书对SEO效果的积极影响

搜索引擎优化(SEO)作为提升网站可见度和吸引有机流量的关键策略,其规则与标准也在不断进化以适应这些变化。其中,安装SSL证书对SEO效果产生的正面影响尤为显著。以下是关于安装SSL证书如何促进SEO效果的详细分析。 一、搜索引擎的…

【Ajax零基础教程】-----第四课 简单实现

一、XMLHttpRequest对象 通过XMLHttpRequest对象来向服务器发送异步请求,从服务器获取数据。然后用JavaScript来操作DOM而更新页面。XMLHttpRequest是ajax的核心机制,它是IE5中首先引入的,是一种支持异步请求的技术。 简单的说,也…

【python量化交易】qteasy使用教程05——创建第一个自定义交易策略

创建第一个自定义交易策略 使用qteasy创建自定义交易策略开始前的准备工作本节的目标自定义策略的实现方法使用 qteasy 的 Strategy 策略类三种不同的自定义策略基类定义一个双均线择时交易策略定义策略运行时机定义策略需要的数据自定义交易策略的实现:realize()获…

SwiftUI 调整视图内容周围间隙(Content Margins)的“时髦”方法

概述 在 SwiftUI 开发的应用中,往往在小屏设备(比如 iPhone)上布局良好的 App 放到大屏(iPad)上后就会“一塌糊涂”。因为它们一味的只想着“占据”却不知道“舍弃”。 从 iOS 17.0(iPad 17.0)开始苹果提供了原生的视图修改器方法专注于处理此事。 在本篇博文中,您将…

pyqt 工具栏QToolBar控件

pyqt 工具栏QToolBar控件 QToolBar控件介绍效果代码 QToolBar控件介绍 QToolBar 是 PyQt(中的一个控件,它提供了一个工具栏,通常包含一系列的工具按钮或下拉菜单,用于提供对应用程序功能的快速访问。 QToolBar 通常与 QMainWind…

霍金《时间简史 A Brief History of Time》书后索引(E--H)

A–D部分见:霍金《时间简史 A Brief History of Time》书后索引(A–D) 图源:Wikipedia INDEX E Earth: circumference, motion, shape Eclipses Eddington, Arthur Einstein, Albert: biography, see also Relativity; Special…

hadoop大数据的一些知识点--Map reduce编程

实验4 MapReduce编程(2) 本实验的知识地图如图4-1所示( 表示重点 表示难点)。 图4-1 实验4MapReduce编程(2)知识地图 一、实验目的 1. 理解YARN体系架构。 2. 熟练掌握YARN Web UI界面的使用。 3. 掌握YARN Shell常用命令的使用。 4. 了解YARN编程之…

Linux 第二十七章

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要等到什么都没有了…

前端本地调试云效上Vue项目的构建产物

一、问题背景 前两天前端小伙伴,在云效上构建了一个前端项目,构建结果显示成功,访问后发现Console控制台报错:ReferenceError: defineComponent is not defined 在此之前的版本,构建和访问并没有此异常,而…

HNU操作系统小班讨论-Windows、Linux文件系统

【题目描述】 叙述Windows、Linux文件系统的演化,比较他们的优劣 【PPT展示】