【数据结构取经之路】栈

目录

引言

栈的性质

顺序栈 

栈的基本操作 

初始化 

销毁

插入

删除

判空

取栈顶元素

栈的大小

完整代码: 


引言

栈(stack),可以用数组实现,也可以用链表实现。用数组实现的栈叫顺序栈,用链表实现的栈叫链式栈,本文讲解的是顺序栈。栈,作为一种特殊的数据结构,在一些方面有着重要用途,例如,快速排序的非递归实现就需要借助栈来完成。

栈的性质

栈是限定仅在栈顶进行插入或删除操作的线性表。它是遵循“后进先出”的原则的,队列正好与之相反。

顺序栈 

 底层用数组实现,当数组空间不够用时就扩容。这些操作和用数组来实现通讯录如出一辙,想必大家已轻车熟路,这里就点到为止了。

栈的基本操作 

因为顺序栈的底层是用数组实现,所以本质上还是在操作数组。

初始化 

初始化操作一般有两种,第一种,在初始化时就给数组分配一定的空间,第二种,初始化时不给分配空间,第一次插入数据时才个数组分配空间。这两种方法用哪一种都无可厚非,按自己喜好来就好,这里呢我就偏爱第二种方法。

代码:

typedef int StackDataType;

typedef struct Stack
{
	StackDataType* a;
	int capacity;//容量
	int top;
}Stack;
void StackInit(Stack* pst)
{
    assert(pst);
	pst->a = NULL;
	pst->capacity = 0;//容量
	pst->top = 0;
}

 需要注意的一个细节是,top指向的是栈顶元素的下一个,以防返回栈顶元素时出现错误。细心观察也会发现,top的值就是栈中的元素个数,这样,返回栈的大小就简单了。

销毁

因为底层使用数组实现,所以要释放数组空间只需要free一把就行了。

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

插入

底层用数组实现,那么在插入时就有可能面临着空间不够的问题,所以在插入之前,需要判断数组是否已满。

代码:

void StackPush(Stack* pst, StackDataType x)
{
	assert(pst);
	if (pst->capacity == pst->top)
	{
		int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		StackDataType* tmp = (StackDataType*)realloc(pst->a, sizeof(StackDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("malloc fail");
			return;
		}
        pst->a = tmp;
	}

	pst->a[pst->top] = x;
	pst->top++;
}

删除

顺序栈的删除实际上就是数组最后一个元素的删除,不需要挪动数据,top--即可,这样即使数组中还存在该元素,但是已经访问不到了。

代码:

void StackPop(Stack* pst)
{
	assert(pst);
	pst->top--;
}

判空

空的特征是:top为0,所以只需要判断top是否为0即可。

代码:

bool StackEmtpy(Stack* pst)
{
	assert(pst);
	return pst->top == 0;
}

取栈顶元素

栈顶元素的下标为top-1,返回该下标对应的值即可。

代码:

StackDataType StackTop(Stack* pst)
{
	assert(pst);
	return pst->a[pst->top - 1];
}

虽然简单,但请不要写成pst->a[pst->top--]. 后置--是有副作用的,也就是说会改变top的值,但这里不需要改变top的值。当然,这种错误是极小概率事件,只是顺便提一提。

栈的大小

top的值就是栈的大小,所以返回top即可。

代码:

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

完整代码: 


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


typedef int StackDataType;

typedef struct Stack
{
	StackDataType* a;
	int capacity;//容量
	int top;
}Stack;

void StackInit(Stack* pst);

void StackDestroy(Stack* pst);

void StackPush(Stack* pst, StackDataType x);

void StackPop(Stack* pst);

bool StackEmtpy(Stack* pst);

StackDataType StackTop(Stack* pst);

int StackSize(Stack* pst);


void StackInit(Stack* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->capacity = 0;
	pst->top = 0;
}

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

void StackPush(Stack* pst, StackDataType x)
{
	assert(pst);
	if (pst->capacity == pst->top)
	{
		int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		StackDataType* tmp = (StackDataType*)realloc(pst->a, sizeof(StackDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("malloc fail");
			return;
		}

		pst->a = tmp;
	}

	pst->a[pst->top] = x;
	pst->top++;
}


void StackPop(Stack* pst)
{
	assert(pst);
	pst->top--;
}


bool StackEmtpy(Stack* pst)
{
	assert(pst);
	return pst->top == 0;
}


StackDataType StackTop(Stack* pst)
{
	assert(pst);
	return pst->a[pst->top - 1];
}

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

 

 

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

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

相关文章

PriorityQueue集合源码分析

PriorityQueue集合源码分析 文章目录 PriorityQueue集合源码分析前置知识一、字段分析二、构造函数分析三、方法分析四、总结 PriorityQueue 优先级队列&#xff0c;是基于堆的结构来构建的。而堆是基于完全二叉树来实现的&#xff0c;而二叉树除了可以用节点来实现也可以用数组…

移动WEB开发之流式布局

一、移动端基础 1、浏览器 总结&#xff1a;兼容移动端主流浏览器&#xff0c;处理webkit内核浏览器即可。 2、移动端调试方法 Chrome devtools&#xff08;谷歌浏览器&#xff09;的模拟手机调试 搭建本地web服务器&#xff0c;手机和服务器一个区域网内&#xff0c;通过手机…

SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测

SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测 目录 SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测预测效果基本介绍模型描述程序…

框架篇常见面试题

1、Spring框架的单例bean是线程安全的吗&#xff1f; 2、什么是AOP&#xff1f; 3、Spring的事务是如何实现的&#xff1f; 4、Spring事务失效的场景 5、SpringBean的声明周期 6、Spring的循环依赖 7、SpringMVC的执行流程 8、SpringBoot自动配置原理 9、Spring常见注解

解决MySQL “Lock wait timeout exceeded; try restarting transaction“ 错误

在处理MySQL数据库时&#xff0c;我们偶尔会遇到一个棘手的错误消息&#xff1a;“Lock wait timeout exceeded; try restarting transaction”。这通常表明我们的一个事务在尝试获取资源时被阻塞了太长时间。在并发环境中&#xff0c;多个事务同时竞争相同的资源可能会导致这种…

安卓手机切换国内IP地址的几种方法详解

随着互联网的普及和移动设备的广泛使用&#xff0c;IP地址已经成为了日常生活中不可或缺的一部分。IP地址不仅可以帮助大家在互联网上找到目标设备&#xff0c;还可以为网络安全提供一定的保障。然而&#xff0c;在某些情况下&#xff0c;可能需要切换国内IP地址&#xff0c;例…

SpringCloud Bus 消息总线

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅&#xff0c;从传统的模块之间调用&#xff0c;一步步的升级为 SpringCloud 模块之间的调用&#xff0c;此篇文章为第八篇&#xff0c;即介绍 Bus 消息总线。 二、概述 2.1 遗留的问题 在上一篇文章的最后&#xff0c;我…

源码部署LAMP架构

LAMP 文章目录 LAMP1. lamp简介2. web服务器工作流程2.1 cgi与fastcgi2.2 httpd与php结合的方式2.3 web工作流程 3. LAMP平台构建3.1 安装httpd3.2 安装mysql3.3 安装php3.4 验证 1. lamp简介 有了前面学习的知识的铺垫&#xff0c;今天可以来学习下第一个常用的web架构了。 …

腾讯云服务器按月收费价格表,优惠价格5元一个月起

2024腾讯云服务器多少钱一个月&#xff1f;5元1个月起&#xff0c;腾讯云轻量服务器4核16G12M带宽32元1个月、96元3个月&#xff0c;8核32G22M配置115元一个月、345元3个月&#xff0c;腾讯云轻量应用服务器61元一年折合5元一个月、4核8G12M配置646元15个月、2核4G5M服务器165元…

● 647. 回文子串 ● 516.最长回文子序列 ● 动态规划总结篇

● 647. 回文子串 1.dp数组含义。 之前的题目&#xff0c;差不多都是求什么就怎么定义dp数组&#xff0c;最后返回dp的最后一个元素。但是这里如果定义一维数组dp[i]是[0,i]范围的回文子串的个数的话&#xff0c;怎么根据dp[i-1]得到dp[i]&#xff1f;发现很难找到递归关系…

窗口函数(sample database classicmodels _No.8 )

窗口函数&#xff08;sample database classicmodels _No.8 &#xff09; 准备工作&#xff0c;可以去下载 classicmodels 数据库具体如下 点击&#xff1a;classicmodels 也可以去 下面我的博客资源下载 https://download.csdn.net/download/tomxjc/88685970 文章目录 窗口函…

Java八股文(RabbitMQ)

Java八股文のRabbitMQ RabbitMQ RabbitMQ RabbitMQ 是什么&#xff1f;它解决了哪些问题&#xff1f; RabbitMQ 是一个开源的消息代理中间件&#xff0c;用于在应用程序之间进行可靠的异步消息传递。 它解决了应用程序间解耦、消息传递、负载均衡、故障恢复等问题。 RabbitMQ …

鸿蒙开发学习:【appspawn应用孵化组件】

功能简介 应用孵化器&#xff0c;负责接受应用程序框架的命令孵化应用进程&#xff0c;设置其对应权限&#xff0c;并调用应用程序框架的入口。 基本概念 appspawn注册的服务名称为“appspawn”。appspawn 通过监听本地socket&#xff0c;接收来自客户端的请求消息。消息类型…

Linux-MDK can电机带导轨 C++封装

我使用的是MKS的52D can电机带导轨&#xff0c;现在我要根据电机说明书将运动指令封装&#xff0c;有一个限位开关&#xff0c; 闭合时高电平 滑块需要运动在限位开关左侧&#xff0c;所以限位归零的方向为顺时针 根据说明书&#xff0c;我要设置的命令应该是&#xff1a; ca…

JavaScript实现简单的表单验证

关键代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

13|连接数据库:通过链和代理查询鲜花信息

新的数据库查询范式 提出问题&#xff1a;用户用自然语言提出一个问题&#xff0c;例如“去年的总销售额是多少&#xff1f;”。LLM 理解并转译&#xff1a;LLM 首先会解析这个问题&#xff0c;理解其背后的意图和所需的信息。接着&#xff0c;模型会根据解析的内容&#xff0c…

蓝桥杯---代分数

import java.util.Scanner;public class top4 {//全排列分数的那个题目//首先进行n个数的全排列//然后将这n个数字拆分为3个数字&#xff0c;即插入两个板子//然后判断等式是否成立&#xff08;判断条件就是在if里面去进行相关的判断是吗&#xff1f;&#xff1f;&#xff09;s…

一文搞懂机器学习

一、引言 在当今的数字时代&#xff0c;一个概念不断出现在科技前沿的讨论中 —— 机器学习。作为人工智能领域的一个重要分支&#xff0c;机器学习已经从理论研究走向实际应用&#xff0c;深刻地改变着我们的工作和生活方式。 机器学习的核心思想是让机器通过数据学习并做出…

【教学类-44-08】20240319 “(幼儿用)数字练习簿1.0”(A4版)

背景需求&#xff1a; 我一直想把 “&#xff08;幼儿用&#xff09;数字练习簿”的内容复刻出来——这里面的字体始终找不到&#xff0c;是一种已经做成图片的手写数字字体 素材准备&#xff1a; 1、买了一本&#xff08;幼儿用&#xff09;数字练习簿&#xff0c;把每一页扫…

蓝桥杯--基础(哈夫曼)

import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Scanner;public class BASIC28 {//哈夫曼书public static void main(String[] args) {Scanner Scannernew Scanner(System.in);int nScanner.nextInt();List<Integer&…