当前位置: 首页 > news >正文

数据结构——关于栈

1.栈

1.1栈的概念及结构


栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作

进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出的原则

比如:羽毛球桶,弹夹等等


压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶

出栈:栈的删除操作叫做出栈,出数据也在栈顶


2. 动态栈的实现

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

Stack.h

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>typedef int STDataType;
typedef struct Stack
{STDataType* a;//指向数组的指针,命名为aint top;// 栈顶int capacity; // 容量
}ST;// 初始化栈
void StackInit(ST* pst);// 销毁栈
void StackDestroy(ST* pst);// 入栈
void StackPush(ST* pst, STDataType x);// 出栈
void StackPop(ST* pst);// 获取栈顶元素top
STDataType StackTop(ST* pst);// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(ST* pst);// 获取栈中有效元素个数
int StackSize(ST* pst);


Stack.c

 初始化栈

// 初始化栈
void StackInit(ST* pst)
{assert(pst);pst->a = NULL;// top为-1直接指向栈顶元素// pst->top = -1;//top为0直接指向栈顶元素的下一个位置pst->top = 0;pst->capacity = 0;
}

 如:

 

 

销毁栈

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

入栈/插入

// 入栈/插入
void StackPush(ST* pst, STDataType x)
{assert(pst);//扩容if (pst->top == pst->capacity){//如果capacity为0,则初始化给4,如果不为0,则原来的空间*2int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;//放数据pst->top++;//如果是给与-1则是先top++再放数据
}

 出栈/删除

// 出栈/删除
void StackPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}

获取栈顶元素top 

// 获取栈顶元素top
STDataType StackTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}

判断栈是否为空

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

获取栈中有效元素个数

// 获取栈中有效元素个数
int StackSize(ST* pst)
{assert(pst);//因为top为0接指向栈顶元素的下一个位置,所以在这里相当于sizereturn pst->top;
}


3.全部代码

1.Stack.c

#include "Stack.h"// 初始化栈
void StackInit(ST* pst)
{assert(pst);pst->a = NULL;// top为-1直接指向栈顶元素// pst->top = -1;//top为0直接指向栈顶元素的下一个位置pst->top = 0;pst->capacity = 0;
}// 销毁栈
void StackDestroy(ST* pst)
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}// 入栈/插入
void StackPush(ST* pst, STDataType x)
{assert(pst);//扩容if (pst->top == pst->capacity){//如果capacity为0,则初始化给4,如果不为0,则原来的空间*2int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;STDataType* tmp = (STDataType*)realloc(pst->a, newcapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}pst->a = tmp;pst->capacity = newcapacity;}pst->a[pst->top] = x;//放数据pst->top++;//如果是给与-1则是先top++再放数据
}// 出栈/删除
void StackPop(ST* pst)
{assert(pst);assert(pst->top > 0);pst->top--;
}// 获取栈顶元素top
STDataType StackTop(ST* pst)
{assert(pst);assert(pst->top > 0);return pst->a[pst->top - 1];
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(ST* pst)
{assert(pst);//如果初始化为-1则是 pst->top+1 == 0;return pst->top == 0;
}// 获取栈中有效元素个数
int StackSize(ST* pst)
{assert(pst);//因为top为0接指向栈顶元素的下一个位置,所以在这里相当于sizereturn pst->top;
}

2.Test.c

#include"Stack.h"
#include<stdio.h>
#include<stdlib.h>
//
//int main()
//{
//	// 原地扩容
//	// 异地扩容
//	int* p1 = (int*)malloc(8);
//	printf("%p\n", p1);
//
//	int* p2 = (int*)realloc(p1, 80);
//	printf("%p\n", p2);
//
//	free(p2);
//
//
//	int i = 0;
//	int ret1 = ++i;
//
//	int ret2 = i++;
//
//
//
//	return 0;
//}//int main()
//{
//	ST s;
//	STInit(&s);
//	STPush(&s, 1);
//	STPush(&s, 2);
//	STPush(&s, 3);
//	STPush(&s, 4);
//
//	printf("%d\n", STTop(&s));
//	STPop(&s);
//	printf("%d\n", STTop(&s));
//	STPop(&s);
//	STPop(&s);
//	STPop(&s);
//	STPop(&s);
//
//	//printf("%d\n", STTop(&s));
//
//	STDestroy(&s);
//
//	return 0;
//}int main()
{// 入栈:1 2 3 4// 出栈:4 3 2 1  /  2 4 3 1ST s;STInit(&s);STPush(&s, 1);STPush(&s, 2);printf("%d ", STTop(&s));STPop(&s);STPush(&s, 3);STPush(&s, 4);while (!STEmpty(&s)){printf("%d ", STTop(&s));STPop(&s);}STDestroy(&s);
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • swift微调款框架使用自定义数据集进行通义千问1.5的微调
  • 网站自动化锚文本的实现逻辑
  • Spring websocket并发发送消息异常的解决
  • 保研考研机试攻略:第三章——数学(3)
  • 基于Arch的轻量级发行版Archcraft结合内网穿透实现远程SSH连接
  • Python居然有这么多文件扩展
  • Docker手动在虚拟机上部署前端、后端和数据库
  • SAP LE学习笔记04 - MM与WM跨模块收货到仓库的流程中 如何既创建TR又同时立即在前台创建TO
  • jmeter安装及环境变量配置、Jmeter目录介绍和界面详解
  • Pcie学习笔记(24)
  • Mysql原理与调优-Mysql的内存结构
  • Flask框架探索:轻量级与灵活性的完美结合
  • 入门mysql数据库
  • 空状态设计教程:连接用户体验的桥梁
  • 制造企业MES系统质检管理的应用
  • 5、React组件事件详解
  • Babel配置的不完全指南
  • codis proxy处理流程
  • HTTP--网络协议分层,http历史(二)
  • mysql 5.6 原生Online DDL解析
  • mysql innodb 索引使用指南
  • php的插入排序,通过双层for循环
  • python学习笔记 - ThreadLocal
  • select2 取值 遍历 设置默认值
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • windows下使用nginx调试简介
  • 快速构建spring-cloud+sleuth+rabbit+ zipkin+es+kibana+grafana日志跟踪平台
  • 什么是Javascript函数节流?
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 听说你叫Java(二)–Servlet请求
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 学习ES6 变量的解构赋值
  • 阿里云ACE认证之理解CDN技术
  • 阿里云移动端播放器高级功能介绍
  • ​一些不规范的GTID使用场景
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #nginx配置案例
  • #QT(一种朴素的计算器实现方法)
  • #QT项目实战(天气预报)
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (03)光刻——半导体电路的绘制
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (第27天)Oracle 数据泵转换分区表
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (剑指Offer)面试题34:丑数
  • (解决办法)ASP.NET导出Excel,打开时提示“您尝试打开文件'XXX.xls'的格式与文件扩展名指定文件不一致
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (五)MySQL的备份及恢复
  • (转)为C# Windows服务添加安装程序
  • **python多态
  • . NET自动找可写目录