【数据结构】栈的实现

news2024/11/28 0:31:50

😛作者:日出等日落

📘 专栏:数据结构

🌹 如果说,读书是在奠定人生的基石,在梳理人生的羽毛,那么,实践,就是在构建人生的厅堂,历练人生的翅膀。是不是,人生经过了实践,才能真正矗立、飞翔在天地之间。

 

目录

1. 栈 

1.1 栈的概念及结构

 1.2栈的实现

1.2.1 入栈

1.2.2 出栈

2. 栈的代码实现(采用数组栈): 

2.1 结构体:

 2.2 StackInit函数:

2.3 StackDestory函数: 

2.4 StackPush 函数: 

 2.5 StackTop函数:

2.6 StackPop函数:

2.7 StackEmpty函数:

2.8 StackSize函数:

3. 完整代码:

3.1 Stack.h(函数的定义):

3.2 Stack.c(功能函数):

3.3 Text.c: 


 

1. 栈 

1.1 栈的概念及结构

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

 

 

 1.2栈的实现

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

1.2.1 入栈

 

 

1.2.2 出栈

 

2. 栈的代码实现(采用数组栈): 

2.1 结构体:

 

 2.2 StackInit函数:

//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("realloc fail:");
		exit(-1);
	}

	ps->capacity = 0;
	ps->top = 0;
}

2.3 StackDestory函数: 

// 销毁栈
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

2.4 StackPush 函数: 

// 入栈
void StackPush(ST* ps, STDataType data)
{
	assert(ps);
	//扩容
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail:");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = data;
	ps->top++;
}

 2.5 StackTop函数:

// 获取栈顶元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->top - 1;
}

2.6 StackPop函数:

// 删除栈顶元素
void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

2.7 StackEmpty函数:

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top = 0;
}

2.8 StackSize函数:

//获取栈中有效元素个数
int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

3. 完整代码:

3.1 Stack.h(函数的定义):

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


//动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top; // 栈顶
	int capacity; // 容量
}ST;
// 初始化栈
void StackInit(ST* ps);

// 销毁栈
void StackDestroy(ST* ps);

// 入栈
void StackPush(ST* ps, STDataType data);

// 删除栈
void StackPop(ST* ps);

// 获取栈顶元素
STDataType StackTop(ST* ps);

// 获取栈中有效元素个数
int StackSize(ST* ps);

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(ST* ps);



3.2 Stack.c(功能函数):

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->a == NULL)
	{
		perror("realloc fail:");
		exit(-1);
	}

	ps->capacity = 0;
	ps->top = 0;
}

// 销毁栈
void StackDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

// 入栈
void StackPush(ST* ps, STDataType data)
{
	assert(ps);
	//扩容
	if (ps->top == ps->capacity)
	{
		STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail:");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity *= 2;
	}
	ps->a[ps->top] = data;
	ps->top++;
}

// 删除栈顶元素
void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	ps->top--;
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top = 0;
}

// 获取栈顶元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));
	return ps->top - 1;
}

//获取栈中有效元素个数
int StackSize(ST* ps)
{
	assert(ps);

	return ps->top;
}


3.3 Text.c: 

#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"


void TextStack1()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	StackPush(&st, 5);

	printf("size:%d\n", StackSize(&st)); // 不关心底层实现
	//printf("size:%d\n", st.top);  // 关心
	printf("size:%d\n", st.top + 1);  // 关心


	StackPop(&st);
	StackPop(&st);
	StackPop(&st);
	StackPop(&st);
	StackPop(&st);
	//StackPop(&st);
	//printf("%d\n", StackTop(&st));

	StackDestroy(&st);
}
int main()
{

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里P7晒工资条,看完好扎心了……

前几天&#xff0c;有位老粉私信我&#xff0c;说看到某95后学弟晒出阿里P7的工资单&#xff0c;他是真酸了…想狠补下技术&#xff0c;努力冲一把大厂。 为了帮到他&#xff0c;也为了大家能在最短的时间内做面试复习&#xff0c;我把软件测试面试系列都汇总在这一篇文章了。 …

自然语言处理: 知识图谱的十年

动动发财的小手&#xff0c;点个赞吧&#xff01; NLP 中结合结构化和非结构化知识的研究概况 自 2012 年谷歌推出知识图谱 (KG) 以来&#xff0c;知识图谱 (KGs) 在学术界和工业界都引起了广泛关注 (Singhal, 2012)。作为实体之间语义关系的表示&#xff0c;知识图谱已被证明与…

ECharts 横向柱状图自动滚动

核心代码 const seriesList [120, 200, 150, 80, 70, 110, 130, 120, 200, 150, 120, 200]; const xAxisList [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; const dataZoomEndValue 6; // 数据窗口范围的结束数值(一次性展示几个) dataZoom: [{show: false, // 是否显示滑动…

Java面向对象高级【类加载器】

目录 Java程序是怎样被运行的 类加载器的作用 加载类文件 链接类 定位类 类加载器间的委派 实现类的隔离 类加载器的类型 启动类加载器&#xff08;Bootstrap Class Loader&#xff09; 扩展类加载器&#xff08;Extension Class Loader&#xff09; 应用程序类加载器…

数据结构和算法学习记录——二叉树的非递归遍历(中序遍历、先序遍历、后序遍历)

目录 中序遍历 代码实现 思路图解 先序遍历 代码实现 后序遍历 思路图解 二叉树的非递归遍历运用到堆栈 中序遍历 循环的思路是 遇到一个节点&#xff0c;就把它压栈&#xff0c;并去遍历它的左子树。当左子树遍历结束之后&#xff0c;从栈顶弹出这个节点并访问…

MybatisPlus主键策略

Mybatis默认主键策略是TableId(type IdType.ASSIGN_ID) 这是默认策略雪花算法 此时主键类型可以是String 数据表字段类型可以是bigint int varchar 无需数据表主键自增 TableId(type IdType.ASSIGN_AUTO) 是主键自增策略:该策略为跟随数据库表的主键递增策略&…

大数据挖掘建模平台产品功能特点

大数据挖掘建模平台是面向大数据挖掘教学实训的工具。在“泰迪杯”数据挖掘挑战赛中大多学生都有使用到该工具&#xff0c;平台采用可视化操作方式&#xff0c;通过丰富内置算法&#xff0c;帮助用户快速、一站式的进行数据分析及挖掘建模。可应用于处理海量数据、高复杂性的数…

C语言判断素数的实现及数学原理

本篇博客会讲解如何使用C语言来判断一个整数是不是素数。 实现方法 如何判断一个数是不是素数呢&#xff1f;如果这个数只能被1或者它自己整除&#xff0c;那么它就是一个素数。 如何写代码来判断呢&#xff1f;假设要判断一个数num是不是素数&#xff0c;就让2~(num-1)的数…

LeetCode037之解数独(相关话题:回溯法)

题目描述 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)数独部分空格内已填入了数字,空白格用 . 表示…

Nginx入门和使用

Nginx入门 基础 https://blog.csdn.net/weixin_40792878/article/details/83316519 快速入门 Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;特点是占有内存少&#xff0c;并发能力强&#xff1b; 代理&#xff1a;用于隐藏客户端或者目标服务器&#xff0c;是客…

通过案例来了解响应式开发(HTML,CSS)的视频控件

目录 前言 一、视频控件的使用方法 1.语法 二、部分属性 二、案例举例 三、播放效果 前言 1.本文讲解的响应式开发技术&#xff08;HTML5CSS3Bootstrap&#xff09;的HTML5表单等功能方法的代码&#xff0c;这也是很多教材的一个典型案例&#xff1b; 2.本文将讲解涉及到…

腾讯轻联测试预览报错怎么办?

在腾讯轻联配置过程中&#xff0c;经常遇到测试预览失败的报错。首先我们整体介绍一下【测试预览】的作用。增加【测试预览】的节点的作用主要有两个&#xff1a; ● 第一个作用是为了保证我们应用连接能通畅&#xff0c;可以获取到数据&#xff0c;避免后续由于设置问题&…

IntelliJ IDEA安装及jsp开发环境搭建

一、前言 现在.net国内市场不怎么好&#xff0c;公司整个.net组技术转型&#xff0c;就个人来说还是更喜欢.net&#xff0c;毕竟不是什么公司都像微软一样财大气粗开发出VS这样的宇宙级IDE供开发者使用&#xff0c;双击sln即可打开项目&#xff0c;一直想吐槽为嘛java项目只能i…

Docker Registry 本地镜像发布到私有库

本地镜像发布到私有库流程 是什么1 官方Docker Hub地址&#xff1a;https://hub.docker.com/&#xff0c;中国大陆访问太慢了且准备被阿里云取代的趋势&#xff0c;不太主流。2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便&#xff0c;涉及机密的公司不可能提供镜像给公…

【Spring Security】 入门实战

文章目录一、基本概念二、Spring Security第一个程序三、Spring Security没有生效四、修改默认账号密码&#xff08;appliction.yml&#xff09;五、修改默认账号密码&#xff08;配置类&#xff09;六、Spring Security的三个configure方法七、Spring Security的三种身份的验证…

Android 面试—深入理解Android类加载机制

前言 任何一个java程序都是由一个或者多个class文件组成&#xff0c;在程序运行时&#xff0c;需要将class文件加载到JVM中才可以使用&#xff0c;负责加载这些class文件的就是java的类加载机制。ClassLoader的作用简单的来说就是加载class文件&#xff0c;提供给程序运行时使…

结构体联合体sizeof内存求值 - 对齐数

讲解下struct和union的内存求值和对齐 以题目讲解 结构体联合体sizeof内存求值 - 对齐数不同位数下类型字节大小内存对齐规则struct 内存对齐求值嵌套struct内存对齐求值union的内存大小求值union大小计算准则struct嵌套union内存对齐求值不同位数下类型字节大小 一定要搞清楚…

【机器学习】P18 反向传播(导数、微积分、链式法则、前向传播、后向传播流程、神经网络)

反向传播反向传播反向传播中的数学导数与python链式法则简单神经网络处理流程从而理解反向传播神经网络与前向传播神经网络与反向传播反向传播 反向传播&#xff08;back propagation&#xff09;是一种用于训练神经网络的算法&#xff0c;其作用是计算神经网络中每个参数对损…

【Java虚拟机】JVM核心基础和常见参数实战

1.新版JVM内存组成部分和堆空间分布 JVM内存的5大组成&#xff08;基于JDK8的HotSpot虚拟机&#xff0c;不同虚拟机不同版本会有不一样&#xff09; 名称作用特点程序计数器也叫PC寄存器&#xff0c;用于记录当前线程执行的字节码指令位置&#xff0c;以便线程在恢复执行时能…

常见的DNS攻击与相应的防御措施

DNS查询通常都是基于UDP的&#xff0c;这就导致了在查询过程中验证机制的缺失&#xff0c;黑客很容易利用该漏洞进行分析。DNS服务可能面临如下DNS攻击风险&#xff1a; 黑客伪造客户端源IP地址发送大量的DNS请求报文&#xff0c;造成DNS request flood攻击。 黑客伪造成授权服…