数据结构--栈

embedded/2024/9/23 18:06:04/

什么是栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端
称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。后进先出的意思是,后进入的数据在出栈的时候最先出来就如下图所示
在这里插入图片描述
栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
这里我们用数组来实现栈的创建

栈的创建

首先我们来画图看看
在这里插入图片描述
这就是我们要创建的栈的样式,首先我们要创建一个结构体来维护栈
为了方便,我们把结构体,还有数据类型重定义一下

typedef int data_type;
typedef struct stack stack;

这是我们的结构体

struct stack
{data_type* arr;int capactiy;//容量int top;//栈顶
};

有了以上的准备,我们下面要进行栈的初始化

栈的初始化

void init_stack(stack* pst)
{pst->arr = NULL;pst->top = 0;//top等于0就代表top == capactiypst->capactiy = 0;
}

这里就是常见的初始化,首先把我们的数组给初始化为空
这里的top初始化就要注意了,如果我们把top置为0,那么就代表我们的数组里面放入了数据,如下图所示
在这里插入图片描述
另一个就是把top初始化为-1,如下图所示
在这里插入图片描述
把top设置为0,就代表top和数据存放的个数一样,top就等于实际有效数据,如果设置成-1,就代表实际有效数据是top+1,这个会影响后面判断栈空间是否满了。

申请空间,入栈

下面是代码

void creative_space(stack* pst,data_type x)
{assert(pst);if (pst->top == pst->capactiy){int newcapcity = pst->capactiy == 0 ? 4 : 2 * pst->capactiy;data_type* temp_space = (data_type*)realloc(pst->arr,sizeof(data_type) * newcapcity);if (temp_space == NULL){perror("temp_space_fail");exit(1);}pst->arr = temp_space;pst->capactiy = newcapcity;}pst->arr[pst->top] = x;pst->top++;
}

这里我们首先要判断,传过来的栈有没有初始化,是否是合法的然后判断如果top等于capacity的化就代表空间满了需要扩容,这里使用了realloc来扩容

int newcapcity = pst->capactiy == 0 ? 4 : 2 * pst->capactiy;

这段代码我们设计的非常巧妙,如果是首次创建栈capacity初始化是0,0乘以任何数都是0,所以我们就需要给他赋一个初始值,用来扩容这里给了一个4,然后就是申请空间了,如果空间不够就以当前空间的二倍来进行扩容,扩容完成之后就是把数据放入栈,top自己++了

拿出栈顶数据

下面是代码

//拿出栈顶数据
data_type get_top_data(stack* pst)
{assert(pst);assert(pst->top > 0);return pst->arr[pst->top-1];
}

我们在拿数据的时候也要判断当前栈是不是为空的,并且top是要大于0的,里面是必须要有数据可供拿出的,最后就返回数组下标,就成功拿出来了

删除栈顶数据

下面是代码

//删除栈顶数据
void del_top_data(stack* pst)
{assert(pst && pst->top>0);pst->top = pst->top - 1;
}

删除很简单,我们只需要 把top的有效位向后移动一位,就代表删除了,同时也要断言一下栈必须存在,并且栈区里面要有数据才能进行删除。

判空

bool st_empty(stack* pst)
{assert(pst);if (pst->top == 0){return true;}else{return false;}
}

同样,这里的判空就是利用top来判断的,返回的类型是布尔类型

获取栈内存放数据的个数

int get_number(stack* pst)
{assert(pst);return pst->top;
}

源码

stack.c

# include"head.h"
void init_stack(stack* pst)
{pst->arr = NULL;pst->top = 0;//top等于0就代表top == capactiypst->capactiy = 0;
}
//删除
void del_stack(stack* pst)
{ assert(pst);free(pst->arr);pst->arr = NULL;pst->top = 0;pst->capactiy = 0;}
//申请空间,入栈
void creative_space(stack* pst,data_type x)
{assert(pst);if (pst->top == pst->capactiy){int newcapcity = pst->capactiy == 0 ? 4 : 2 * pst->capactiy;data_type* temp_space = (data_type*)realloc(pst->arr,sizeof(data_type) * newcapcity);if (temp_space == NULL){perror("temp_space_fail");exit(1);}pst->arr = temp_space;pst->capactiy = newcapcity;}pst->arr[pst->top] = x;pst->top++;
}
void print_stack(stack* pst)
{assert(pst);assert(pst->top > 0);int i = pst->top;i--;while (i >= 0){printf("%d",pst->arr[i]);i--;}
}
//拿出栈顶数据
data_type get_top_data(stack* pst)
{assert(pst);assert(pst->top > 0);return pst->arr[pst->top-1];
}
//删除栈顶数据
void del_top_data(stack* pst)
{assert(pst && pst->top>0);pst->top = pst->top - 1;
}
//判空
bool st_empty(stack* pst)
{assert(pst);if (pst->top == 0){return true;}else{return false;}
}
int get_number(stack* pst)
{assert(pst);return pst->top;
}

test.c

# include"head.h"
void test()
{stack st;init_stack(&st);creative_space(&st, 1);creative_space(&st, 2);creative_space(&st, 3);creative_space(&st, 4);print_stack(&st);data_type b = get_top_data(&st);printf("\n%d",b);int a = get_number(&st);printf("\n%d\n", a);del_top_data(&st);print_stack(&st);int c = get_top_data(&st);printf("\n%d", c);bool n =  st_empty(&st);del_stack(&st);
}
int main()
{test();return 0;
}

stack.h

#pragma once
# include<stdio.h>
# include<stdlib.h>
# include<assert.h>
# include<stdbool.h>
typedef int data_type;
struct stack
{data_type* arr;int capactiy;int top;
};
typedef struct stack stack;void init_stack(stack* pst);
//初始化栈
void creative_space(stack* pst,data_type x);
//申请空间
data_type get_top_data(stack* pst);
//拿出栈顶数据
void print_stack(stack* pst);
//打印数据
void del_top_data(stack* pst);
//栈空没有
bool st_empty(stack* pst);
//获取数据个数
int get_number(stack* pst);


http://www.ppmy.cn/embedded/38266.html

相关文章

RabbiMQ-消息可靠性

RabbiMQ消息可靠性 生产者可靠性 生产者重试机制 问题&#xff1a;生产者发送消息时&#xff0c;出现了网络故障&#xff0c;导致与MQ的连接中断 解决&#xff1a; spring:rabbitmq:connection-timeout: 1s # 设置MQ的连接超时时间template:retry:enabled: true # 开启超时…

如何让vim支持python3

首先删除旧的vim。 sudo apt-get remove vim //输入re按下tab直接显示remove sudo apt-get remove vim-runtime sudo apt-get remove vim -tiny sudo apt-get remove vim-common 然后下载vim8源码&#xff1a; git clone https://github.com/vim/vim.git 进行编译安装…

基于Nios-II的流水灯

基于Nios-II的流水灯 一、Qsys设计&#xff08;一&#xff09;新建项目&#xff08;二&#xff09;Platfrom Designer&#xff08;三&#xff09;设置时钟主频&#xff08;四&#xff09;添加Nios-II Processor并设置&#xff08;五&#xff09;添加JTAG并配置&#xff08;六&a…

C/C++开发,opencv-features2d模块,SIFT等特征检测器应用

目录 一、OpenCV-features2d 模块简介 1.1 features2d 模块信息 1.2 features2d 模块应用流程 二、features2d 模块编码案例 2.1 实现逻辑 2.2 features2d 模块应用程序代码 2.3 程序编译及运行 一、OpenCV-features2d 模块简介 1.1 features2d 模块信息 features2d 是…

第9章 负载均衡集群日常维护

一个设计良好的高可用负载均衡集群&#xff0c;交付使用以后并不能一劳永逸。欲使其高效、稳定、持续对外服务&#xff0c;日常维护必不可少。 对于高可用负载均衡集群来说&#xff0c;有两种类型的维护形式&#xff1a;常规性维护与突发性维护。突发性维护一般指故障处理&…

vue3中 Hook详解 Hook结合自定义指令

Vue3的自定义的hook Vue3的hook函数 相当于vue2的mixin&#xff0c;不用在于hooks是函数 Vue3hook函数 可以帮助我们提高代码的复用性&#xff0c;让我们能在不能的组件中都利用hooks函数 Vue3 hook库: [hook 官网](https://vueuse.org/guide/)手写自定义hook 案例一 1.新建…

JSP技术讲解

目录 1、JSP简介 2、JSP体验 3、JSP运行原理 4、JSP基本语法 5、JSP指令 6、JSP内置九大对象 7、JSP标签 8、JSP配置 9、JSP排错 10、总结 在前面的Servlet学习中发现Servlet本质是一个java程序&#xff0c;因此Servlet更加擅长编写程序的业务逻辑&#xff0c;而如果要…

主成分分析(PCA)学习

概述 主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;是一种常用的数据降维方法&#xff0c;它通过线性变换将原始数据变换为一组各维度线性无关的表示&#xff0c;通常用于提取数据的主要特征分量。PCA 的目标是从原始数据中提取出最重要的特…