栈的实现详解

目录

  • 1. 栈
    • 1.1 栈的概念及结构
    • 1.2 栈的实现方式
    • 1.3 栈的应用场景
  • 2. 栈的实现
    • 2.1 结构体
    • 2.2 初始化
    • 2.3 销毁
    • 2.4 入栈
    • 2.5 出栈
    • 2.6 获取栈顶元素
    • 2.7 判空
    • 2.8 获取个数
  • 3. test主函数
  • 4. Stack.c文件
  • 5. Stack.h文件
  • 6. 运行展示

1. 栈

1.1 栈的概念及结构

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

在这里插入图片描述

在这里插入图片描述

1.2 栈的实现方式

栈可以通过多种方式实现,包括数组和链表等。使用数组实现的栈具有连续的内存空间,操作效率较高;而使用链表实现的栈则更加灵活,可以在动态环境中调整栈的大小。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
实现用的是数据栈。

1.3 栈的应用场景

函数调用:在计算机程序中,函数调用和返回的过程可以用栈来实现。当调用一个函数时,会将函数的返回地址和参数压入栈中;当函数返回时,会从栈中弹出这些信息,并返回到调用点继续执行。
浏览器的前进与后退:在浏览器中,可以使用两个栈来实现前进和后退功能。一个栈记录新访问的页面,另一个栈记录后退弹出的页面。当用户点击前进按钮时,从记录新访问页面的栈中弹出页面;当用户点击后退按钮时,从记录后退页面的栈中弹出页面。
表达式求值:在编译器中,可以使用栈来进行表达式的求值。将运算符和操作数压入栈中,并根据运算符的优先级和结合性进行出栈和计算操作,最终得到表达式的值。

2. 栈的实现

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

在这里插入图片描述

在这里插入图片描述

2.1 结构体

首先要先把结构体定义出来,一个是数组栈,一个是指向栈顶元素的下一个,还有一个是增容。

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//指向栈顶元素的下一个
	int capaicty;
}ST;

2.2 初始化

top等于0指向栈顶元素的下一个位置,top等于-1指向栈顶元素

//初始化
void STInit(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	//pst->top = -1;//指向栈顶元素
	pst->top = 0;//指向栈顶元素的下一个位置
	pst->capaicty = 0;
}

2.3 销毁

防止造成野指针的错误

//销毁
void STDestroy(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->top = 0;
	pst->capaicty = 0;
	free(pst->a);
}

2.4 入栈

先判断容量是否够,再实现动态增容。

//入栈
void STPush(ST* pst, STDataType x)
{
	//扩容
	if (pst->top == pst->capaicty)
	{
		int newCapaicty = pst->capaicty = 0 ? 4 : pst->capaicty * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newCapaicty * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("STPush");
			return;
		}

		pst->a = tmp;
		pst->capaicty = newCapaicty;
	}

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

2.5 出栈

看栈是否空,不是空就不能删,再top减减就行

//出栈
void STPpo(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));

	pst->top--;
}

2.6 获取栈顶元素

因为top指向栈顶元素的下一个,所以top要减1,当然空的时候也要判断一下

//获取栈顶元素
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));

	return pst->a[pst->top - 1];
}

2.7 判空

//判空
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}

2.8 获取个数

打印之前可以看还有多少个在栈中

//获取个数
int STsize(ST* pst)
{
	assert(pst);

	return pst->top;
}

3. test主函数

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "Stack.h"

void TestStack1()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	printf("%d ", STTop(&st));
	STPpo(&st);
	STPush(&st, 3);
	STPush(&st, 4);
	printf("size: %d\n", STsize(&st));
	
	//打印
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));
		STPpo(&st);
	}

	STDestroy(&st);
}

int main()
{
	TestStack1();
	return 0;
}

4. Stack.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"


//初始化
void STInit(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	//pst->top = -1;//指向栈顶元素
	pst->top = 0;//指向栈顶元素的下一个位置
	pst->capaicty = 0;
}

//销毁
void STDestroy(ST* pst)
{
	assert(pst);

	pst->a = NULL;
	pst->top = 0;
	pst->capaicty = 0;
	free(pst->a);
}

//入栈
void STPush(ST* pst, STDataType x)
{
	//扩容
	if (pst->top == pst->capaicty)
	{
		int newCapaicty = pst->capaicty = 0 ? 4 : pst->capaicty * 2;
		STDataType* tmp = (STDataType*)realloc(pst->a, newCapaicty * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("STPush");
			return;
		}

		pst->a = tmp;
		pst->capaicty = newCapaicty;
	}

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

//出栈
void STPpo(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));

	pst->top--;
}

//获取栈顶元素
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));

	return pst->a[pst->top - 1];
}

//判空
bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == 0;
}

//获取个数
int STsize(ST* pst)
{
	assert(pst);

	return pst->top;
}

5. Stack.h文件

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

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//指向栈顶元素的下一个
	int capaicty;
}ST;

//初始化
void STInit(ST* pst);

//销毁
void STDestroy(ST* pst);

//入栈
void STPush(ST* pst, STDataType x);

//出栈
void STPpo(ST* pst);

//获取栈顶元素
STDataType STTop(ST* pst);

//判空
bool STEmpty(ST* pst);

//获取个数
int STsize(ST* pst);

6. 运行展示

在这里插入图片描述

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

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

相关文章

2024.6.14 作业 xyt

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c…

AI Agent智能应用从0到1定制开发(完结)

在数字化时代的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;代理智能应用如同星辰般璀璨&#xff0c;引领着技术革新的潮流。从零开始定制开发一款AI Agent智能应用&#xff0c;就像是在无垠的宇宙中绘制一颗新星的轨迹&#xff0c;每一步都充满了挑战与创新的火花。…

【Photoshop】PS修改文字内容

Photoshop(PS)修改图片上文字内容&#xff0c;网上教材不少&#xff0c;本人整理实践过的方法&#xff0c;分享给各位。本人实践方法&#xff1a; 内容识别填充&#xff1a;适用于背景色复杂的图片内容修补工具&#xff1a;适用于背景色为纯色的图片 方式一&#xff1a;内容识…

HAL库开发--STM32的HAL环境搭建

知不足而奋进 望远山而前行 目录 文章目录 前言 下载 安装 解压 安装 添加开发包 修改仓库路径 下载软件开发包&#xff08;慢&#xff0c;不推荐&#xff09; 解压已有软件开发包&#xff08;快&#xff0c;推荐&#xff09; 总结 前言 在嵌入式系统开发中&#x…

【数据的增值之路】全生命周期的数据演化过程

引言&#xff1a;随着云计算、大数据、人工智能、区块链等新一代信息技术的快速发展&#xff0c;数据已经成为推动经济增长的重要生产要素。数据量的爆炸式增长&#xff0c;为挖掘数据价值、推动数字经济发展提供了丰富的资源基础。重要概念解析&#xff1a; 数据经济&#xf…

【内存管理之指针艺术】

1.记住&#xff1a;不同的类型具有不同的内存大小 2.指针只是存储地址的变量 3.指针艺术&#xff1a;增长1 4.重来 5.指针艺术&#xff1a;减小1 6.指针艺术 6.下标运算符[] 7.指针图解 7.指向对象的指针 7.指向指针的指针

Java—读取properties配置文件

编写配置文件 usernameroot password123456 urljdbc:mysql://localhost:3306/myDatabase driverClassNamecom.mysql.cj.jdbc.Driver 编写测试类 import java.io.FileInputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Properties;/*…

CCAA质量管理【学习笔记】​​ 备考知识点笔记(四)

第四节 质量非数据资料分析的基础工具 1 关 联 图 2.1 概念 所谓关联图&#xff0c;就是对关系复杂而相互纠缠的问题&#xff0c;依据原因—结果或目的一手段等关系&#xff0c; 在逻辑上用箭头把各要素之间的因果关系连接起来&#xff0c;厘清复杂问题、整理语言文字资料…

神舟电脑文件误删怎么办?这些恢复方法助你轻松解决

神舟电脑文件误删怎么办&#xff1f;在信息爆炸的时代&#xff0c;电脑已经成为我们日常生活和工作中不可或缺的重要工具。然而&#xff0c;有时我们会因为一些不小心的操作&#xff0c;误删了电脑中的重要文件&#xff0c;尤其是在使用神舟电脑这类高性能设备时&#xff0c;文…

编译一个叫:未来的IDE-Zed编辑器(Windows平台)

一、前言 截止到2024-6-15&#xff0c;Zed官方并未给出Windows的二进制安装包&#xff0c;如果想在Windows平台使用的话需要自己编译&#xff0c;我是如何编译的请随我道来&#xff0c;有兴趣的码友可以尝试下&#xff0c;在下可不敢保证各位码友按我这方法能100%编译出来&…

RK3568技术笔记八 开发环境的搭建

先按照前面的方法将 ubuntu 安装在 PC 机上。 编译开发Linux系统&#xff0c;虚拟机Ubuntu 系统要求&#xff1a; 64位系统&#xff0c;硬盘空间大于或等于200G&#xff0c;内存不小于6GB。 建议使用 Ubuntu18.04 系统进行编译。 光盘资料&#xff1a;SAIL-RK3568开发板光盘…

SQL编程基础常见题型练习

SQL编程基础常见题型练习 1. 基础查询1.1. 基础查询1.2. 简单处理查询结果 2. 条件查询2.1. 基础排序2.2. 基础操作符2.3. 高级操作符 3. 高级查询3.1. 计算函数3.2. 分组查询 4. 多表查询4.1. 子查询4.2. 链接查询4.3. 组合查询 5. 必会的常用函数5.1. 条件函数5.2. 日期函数 …

将Jar用三种方式生成Windows的安装程序

无论是WEB(spring boot)的JAR,还是JavaFX以及swing的Jar,要生成windows方式。 打包成Windows可执行文件&#xff08;.exe&#xff09;&#xff0c;你可以使用以下三种方法&#xff1a; ### 方法1&#xff1a;使用Inno Setup 1. **构建JavaFX应用程序**&#xff1a; 使用M…

大模型企业落地:制造业可以选择的应用场景

前言 在当今制造业快速发展的背景下&#xff0c;设备稳定运行对于企业的发展至关重要。然而&#xff0c;传统的设备维修模式已无法满足现代企业的需求。为此&#xff0c;引入智能化、数字化的设备维修解决方案成为必然趋势。本文将探讨如何利用大模型技术&#xff0c;构建企业…

Netflix 机器学习科学家的提示词优化经验分享

编者按&#xff1a; 如何充分发挥大模型的潜能&#xff0c;用好大模型&#xff0c;关键在于如何优化向它们发送的提示词&#xff08;prompt&#xff09;&#xff0c;是为提示词工程&#xff08;prompt engineering&#xff09;。 本文Netflix 机器学习科学家Cameron R. Wolfe的…

FPGA - 全局时钟资源

全局时钟资源是指FPGA内部为实现系统时钟到达FPGA内部各 CLB、IOB&#xff0c;以及BSRAM&#xff08;Block Select RAM&#xff0c;选择性BRAM&#xff09;等基本逻辑单元的延时和抖动最小化&#xff0c;采用全铜层工艺设计和实现的专用缓冲与驱动结构。 由于全局时钟资源的布线…

HAL库开发--串口

知不足而奋进 望远山而前行 目录 文章目录 前言 学习目标 学习内容 开发流程 串口功能配置 串口功能开启 串口中断配置 串口参数配置 查询配置结果 发送功能测试 中断接收功能测试 printf配置 DMA收发 配置 DMA发送 DMA接收(方式1) DMA接收(方式2) 总结 前言…

简单了解MySql以及一些简单的应用MySql

MySql基础篇 1、数据模型概述 关系型数据库 概念&#xff1a;建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库。 特点&#xff1a; 使用表存储数据&#xff0c;格式统一&#xff0c;便于维护使用SQL语言操作&#xff0c;标准统一&#xff0c;使用方便 数…

基于Matlab的车牌识别停车场出入库计时计费管理系统(含GUI界面)【W6】

简介&#xff1a; 在当今城市化进程加快的环境下&#xff0c;停车管理成为了一个日益重要和复杂的问题。城市中的停车资源有限&#xff0c;如何高效利用和管理这些资源&#xff0c;不仅关乎市民出行便利性&#xff0c;也涉及到城市交通拥堵、环境污染等诸多问题的解决。 传统的…

计算机网络(7) 错误检测

一.校验和 使用补码计算校验和是一种常见的错误检测方法&#xff0c;应用于网络协议如IP和TCP。补码是二进制数的一种表示方法&#xff0c;可以有效地处理符号位和进位。下面是如何利用补码计算校验和的详细步骤和算数例子。 ### 计算步骤 1. **将数据分块**&#xff1a;将数…