数据结构 —— 栈 与 队列

1.栈

1.1栈的结构和概念

栈(Stack)是一种特殊的线性数据结构,它遵循后进先出(LIFO,Last In First Out)的原则。栈只允许在一端插入和删除数据,这一端被称为栈顶(top),另一端被称为栈底(bottom)。

就像弹匣一样,先压进去的子弹会最后被发射,最后压进去的子弹反而最先被发射

1.2栈的实现 (数组)

栈的基本功能:

  1. push(元素):将元素压入栈顶。
  2.  pop():从栈顶删除元素,并返回该元素。如果栈为空,则此操作可能会导致错误。
  3. peek() 或 top():返回栈顶元素,但不删除它。
  4. Empty():检查栈是否为空。
  5. size():返回栈中元素的数量。

Stack.h

#pragma once
// 支持动态增长的栈
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>

typedef int STDataType;
typedef struct Stack
{
	STDataType* _a;
	int _top;		// 栈顶
	int _capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps);
// 入栈 
void StackPush(Stack* ps, STDataType data);
// 出栈 
void StackPop(Stack* ps);
// 获取栈顶元素 
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数 
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps);
// 销毁栈 
void StackDestroy(Stack* ps);

Stack.c

#include"Stack.h"

// 初始化栈 
void StackInit(Stack* ps) {
	assert(ps);

	ps->_a = NULL;
	ps->_capacity = 0;
	ps->_top = 0;
}
// 入栈 
void StackPush(Stack* ps, STDataType data) {
	assert(ps);

	//扩容
	if (ps->_top == ps->_capacity)
	{
		int newcapacity = ps->_capacity == 0 ? 2 : ps->_capacity * 2;
		STDataType* newa = (STDataType*)realloc(ps->_a,newcapacity * sizeof(STDataType));
		if (newa == NULL)
		{
			perror("realloc");
			return;
		}
		ps->_capacity = newcapacity;
		ps->_a = newa;
	}

	ps->_a[ps->_top] = data;
	ps->_top++;
}
// 出栈 
void StackPop(Stack* ps) {

	assert(ps);
	assert(ps->_top > 0);

	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 
int StackEmpty(Stack* ps) {
	assert(ps);

	return ps->_top == 0;//为空就是真,返回非0

}
// 销毁栈 
void StackDestroy(Stack* ps) {
	assert(ps);

	ps->_top = 0;
	ps->_capacity = 0;
	free(ps->_a);
	ps->_a = NULL;
}

2.队列(单链表)

2.1队列的概念和结构

队列(Queue)是一种特殊的线性表,它遵循先进先出(FIFO)的原则,即最早进入队列的元素将最先从队列中移除。队列只允许在表的前端(front)进行删除操作,称为出队,而在表的后端(rear)进行插入操作,称为入队。

  先进先出,后进后出

2.2队列的实现(链表)

  1. 入队(Push):在队列的尾部添加一个元素。

  2. 出队(Pop):从队列的头部移除一个元素,并返回该元素。

  3. 判断队列是否为空(Empty):检查队列是否不包含任何元素。

  4. 获取队列大小(Size):返回队列中当前元素的数量。

  5. 查看队头元素(Front):返回队列头部的元素,但不从队列中移除它。

  6. 查看队尾元素(Back):返回队列尾部的元素,但不从队列中移除它

Queue.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode
{
	struct QListNode* _next;
	QDataType _data;
}QNode;

// 队列的结构 
typedef struct Queue
{
	QNode* _front;
	QNode* _rear;
	int size;
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);
// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);

Queue.c 

 

#include"Queue.h"

// 初始化队列 
void QueueInit(Queue* q) {
	assert(q);

	q->size = 0;
	q->_front = NULL;
	q->_rear = NULL;
}
// 队尾入队列 
void QueuePush(Queue* q, QDataType data) {
	assert(q);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("QueuePush()::malloc()");
		return;
	}

	newnode->_data = data;
	newnode->_next = NULL;
	
	//队列为NULL
	if (q->_front == NULL)
	{
		q->_front = q->_rear = newnode;
	}
	else
	{
		q->_rear->_next = newnode;
		q->_rear = q->_rear->_next;
	}

	q->size++;
}
// 队头出队列 
void QueuePop(Queue* q) {
	assert(q);
	assert(q->size != 0);

	//单个节点
	if (q->_front == q->_rear)
	{
		free(q->_front);
		q->_front = q->_rear = NULL;
	}
	//多个节点
	else
	{
		QNode* next = q->_front->_next;
		free(q->_front);
		q->_front = next;
	}

	q->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* q) {

	assert(q);
	assert(q->_front);//队头不能为NULL

	return q->_front->_data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* q) {
	assert(q);
	assert(q->_rear);//队尾不能为NULL

	return q->_rear->_data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* q) {

	return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q) {
	assert(q);

	return q->size == 0;
}
// 销毁队列 
void QueueDestroy(Queue* q) {
	assert(q);

	QNode* cur = q->_front;
	while (cur)
	{
		QNode* next = cur->_next;
		free(cur);
		cur = next;
	}

	q->_front = q->_rear = NULL;
	q->size = 0;

	//这个应该留给用户去释放
	/*free(q);
	q = NULL;*/
}

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

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

相关文章

第一节:Redis的数据类型和基本操作

最近整理了关于Redis的一些文档&#xff0c;分享给大家&#xff0c;后续会持续更新...... Redis的数据类型 字符串String String&#xff1a;字符串&#xff0c;可以存储String、Integer、Float型的数据&#xff0c;甚至是二进制数据&#xff0c;一个字符串最大容量是512M 列表…

Linux指令初识

ls:显示当前目录底下的指定文件或目录 ls -l更详细的信息 ls -a显示当前目录下的所有文件 命令中的选项可以一次传递多个 ,例如&#xff1a;ls -al 命令和选项有必须一个或多个空格 以.开头的文件&#xff0c;为隐藏文件ls -a可以看到,ls -l看不见 支持命令拼在一起&#…

【vue2配置】Vue Router

Vue Router官网 1、npm install vue-router4 2、创建模块&#xff0c;在src目录小创/views/map/MapIndex.vue模块和创router/index.js文件 3、在router/index.js配置路由 import Vue from "vue"; import Router from "vue-router"; // 引入模块 const Ma…

C++学习/复习5--构造函数与初始化/static成员/友元/内部类/匿名对象/编译器的拷贝构造优化

一、本章概要 二、再谈构造函数 1.构造体赋初值与初始化 2.初始化列表与初始化 2.1定义 2.2注意事项与举例 3.explicit关键字与构造函数 3.1隐式类型转换 也叫做自动类型转换 这种转换通常是从存储范围小的类型到存储范围大的类型&#xff0c;或者是从低精度的数值类型到高…

【编译原理--- 汇编、编译、解释系统】

汇编、编译、解释系统 1.编译方式和解释方式 程序种类是否生成目标程序是否参与程序的运行过程程序执行速度可移植性编译程序生成不参与快差解释程序不生成参与慢好 编译方式过程&#xff1a;词法分析、语法分析、语义分析、&#xff08;中间代码生成、代码优化、&#xff0…

【动手学强化学习】第 6 章 Dyna-Q 算法知识点总结

【动手学强化学习】第 6 章 Dyna-Q 算法知识点总结 本章知识点基于模型的强化学习与无模型的强化学习方法简介无模型的强化学习方法基于模型的强化学习方法 强化学习算法的评价指标Dyna-Q算法Dyna-Q 算法的具体流程Dyna-Q 代码实践 本章知识点 基于模型的强化学习与无模型的强…

opencv进阶 ——(四)图像处理之去高光

去高光步骤&#xff1a; 1、转换成灰度图 2、二值化图像&#xff0c;得到高光区域 3、进行膨胀操作&#xff0c;放大高光区域&#xff0c;以此得到高光蒙版 4、通过illuminationChange函数对高光区域消除高光

VMware安装Ubuntu系统(超详细)

一.Ubuntu官网下载镜像 Ubuntu官网&#xff1a;Enterprise Open Source and Linux | Ubuntu 二.安装Ubuntu系统 选择文件->创建虚拟机新建虚拟机&#xff08;ControlN&#xff09;&#xff0c;这里直接选择典型即可 选择稍后安装系统 选择linux Ubuntu 64位 填写虚拟机名称…

word一按空格就换行怎么办?word文本之间添加空格就换行怎么办?

如上图&#xff0c;无法在Connection和con之间添加空格&#xff0c;一按空格就会自动换行。 第一步&#xff1a;选中文本&#xff0c;打开段落。 第二步&#xff1a;点击中文版式&#xff0c;勾选允许西文在单词中间换行。 确定之后就解决一按空格就自动换行啦&#xff01;

基于STM32实现智能水族箱控制系统

目录 引言环境准备智能水族箱控制系统基础代码示例&#xff1a;实现智能水族箱控制系统 水温传感器数据读取水泵与加热器控制水位传感器数据读取用户界面与显示应用场景&#xff1a;水族箱管理与环境控制问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌…

steam游戏服务器如何选择

steam游戏平台现在在国内市场很吃香&#xff0c;当我们自己开发的游戏想要上架steam我们需要准备什么&#xff0c;在选择服务器的时候我们又需要考虑哪些因素呢&#xff0c;该怎样选择一款适合自己游戏的服务器是很关键的 一.Steam服务器的配置选择 Steam专用服务器通常是指由…

【wiki知识库】01.wiki知识库前后端项目搭建(SpringBoot+Vue3)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 &#x1f33c;环境准备 想要搭建自己的wiki知识库&#xff0c;要提前搭建好自己的开发环境&#xff0c;后端我使用的是SpringBoot&#xff0c;前端使用的是Vue3&#xff0c;采用前后端分离的技术实现。同时使用了Mysql数…

Spring Boot 3.0:未来企业应用开发的基石

文章目录 一、Spring Boot 3.0的核心特性二、Spring Boot 3.0的优势三、如何在项目中应用Spring Boot 3.01.更新项目依赖2.调整代码结构3.测试和部署 《学习Spring Boot 3.0》内容简介作者简介目录内容介绍 随着技术的飞速发展&#xff0c;企业应用开发的需求也在不断演变。Spr…

创客贴:极简高效的智能平面设计神器测评

给大家推荐一款智能平面设计作图软件——创客贴&#xff0c;简单来说&#xff0c;就是给那些需要频繁进行平面设计的人提供帮助的。它作为一款在线图片编辑器&#xff0c;可以免费使用&#xff0c;让你轻松进行创意设计。创客贴不仅提供了海量正版设计模板和图片素材&#xff0…

AI 谈“浔川AI翻译机”

在天工AI&#xff0c;天工AI在全网搜索“浔川AI翻译机”。 1 创作助手谈“浔川AI翻译机”&#xff1a; “浔川AI翻译机”是一个利用人工智能技术进行语言翻译的设备或应用程序。它可以将一种语言的文字或口语翻译成另一种语言&#xff0c;以实现不同语言之间的沟通和理解。浔…

小猪APP分发:一站式免费应用推广解决方案

在竞争激烈的移动应用市场中&#xff0c;寻找一个高效且成本友好的方式来推广自己的应用程序&#xff0c;成为了众多开发者面临的共同挑战。幸运的是&#xff0c;像"小猪APP分发www.appzhu.cn"这样的平台应运而生&#xff0c;为开发者提供了一个全面、免费的应用分发…

用AI比赛助手降维打击数学建模,比赛过程详细介绍,这保研不就稳了吗

数学建模是个小众的赛道&#xff0c;可能很多大学生不知道&#xff0c;简单来说&#xff1a;他能薅学分、保研加分、毕业好找工作(简历上写一辈子)&#xff0c;尤其是基于GPT-4o模型&#xff0c;简直对他们是降维打击。 数学建模每年的比赛非常多&#xff0c;像国赛、美赛、深…

基于STM32实现智能气体检测报警系统

⬇帮大家整理了单片机的资料 包括stm32的项目合集【源码开发文档】 点击下方蓝字即可领取&#xff0c;感谢支持&#xff01;⬇ 点击领取更多嵌入式详细资料 问题讨论&#xff0c;stm32的资料领取可以私信&#xff01; 目录 引言环境准备智能气体检测报警系统基础代码示例&…

FPGA之tcp/udp

在调试以太网的过程中&#xff0c;考虑了vivado IP配置(管脚、reset等)&#xff0c;SDK中PHY芯片的配置(芯片地址、自适应速率配置等)&#xff0c;但是&#xff0c;唯独忽略了tcp/udp协议&#xff0c;所以在ping通之后仍无法连接。 所以现在来学习一下tcp与udp的区别 ---- 为什…

功率电感的设计步骤

文章目录 1&#xff1a;高导磁气隙&#xff08;铁氧体&#xff09;1.1设计原理1.2 设计步骤 2 铁粉芯2.1&#xff1a;设计原理2.2&#xff1a;设计步骤 TI电感设计 学习视频原链接 截图 1 截图1 截图1 截图 2 截图2 截图2 1&#xff1a;高导磁气隙&#xff08;铁氧体&#…