数据结构顺序栈

news2025/1/29 14:07:00

这是大话数据结构种对于栈的描述

 

可以看到 栈是一种特殊的线性表

它只能在尾部进行元素的插入和删除 但是在栈种 这叫做 入栈出栈 

而且它遵循 先进入的元素后出 后进入的元素先出

即就是我们常听说的 先进后出 和后进先出

这里就有一个简单的例子 先进后出 后进先出 

 

这里有个更加形象的例子 手枪弹夹 我们后装入的子弹位于 弹夹的顶端 因此会被先射出 而先装入的子弹位于弹夹底端 因此会后射出

那么我们的栈的基础结构就和这个手枪弹夹十分类似

栈的结构可以分为顺序栈 和 链式栈 

今天我们介绍 顺序栈

 

我们可以在顺序表的基础上做出修改就可以实现一个顺序栈

这是往期的顺序表的实现 可以参考这个来实现顺序栈 

基础数据结构线性表_iccoke的博客-CSDN博客 

 首先我们给出 顺序栈的结构体定义

#pragma once
//可扩容的顺序栈的结构体设计


#define STACK_INIT_SIZE 100 //初始大小
#define STACK_INCREMENT 10 //不需要
typedef int ELEM_TYPE;

typedef struct Stack
{
	ELEM_TYPE *base;//存储空间基址(用来接收malloc返回在堆上申请的连续空间块开始地址)
	int top;//当前有效长度,且还可以表示下一个待插入位置的下标
	int stack_size;//当前总空间大小(以格子个数为单位)
}Stack, *PStack;

//初始化
void Init_stack(struct Stack *st);

//入栈(队尾插入)
bool Push(struct Stack *st, ELEM_TYPE val);

//出栈(队尾删除)  出栈,将值删除一个
bool Pop(struct Stack *st);

//获取栈顶元素值 //获取栈顶的元素值,但是不删除
ELEM_TYPE Top(struct Stack *st);

//判空
bool Is_Empty(struct Stack *st);

//判满
bool Is_Full(struct Stack *st);

//扩容 *2
void Inc(struct Stack *st);

//搜索
int Search(struct Stack *st, ELEM_TYPE val);

//清空
void Clear(struct Stack *st);

//销毁
void Destroy(struct Stack *st);

//打印
void Show(struct Stack *st);

//获取有效值个数
int Get_length(struct Stack *st);

熟悉顺序表的同学应该可以发现这里的结构体定义实际上顺序表一致

只不过是为了区分因此我们改变了结构体种的变量名

 

然后我们来实现 顺序栈

首先是初始化 我们依旧申请内存来初始化

void Init_stack(struct Stack *st)
{
	st->base = (ELEM_TYPE*)malloc(STACK_INIT_SIZE * sizeof(ELEM_TYPE));
	st->top = 0;//即代表下一个合适的插入位置下标为0,也代表当前有效长度为0
	st->stack_size = STACK_INIT_SIZE;
}

 初始化的时候栈中是没有元素的 因此我们的top 是 0

但是因为栈有大小 因此我们给点大小 用stack_size 宏来初始化

那么也就意味着我们现在在插入 和 删除 时都需要进行判断

插入时 判断是否为满 如果 满 进行插入失败 或者 扩容操作

删除时依旧 要判断是否为空

接下来 我们写 顺序栈中最重要的两个函数 

入栈

bool Push(struct Stack *st, ELEM_TYPE val)
{
	//0.安全性处理
	assert(st != NULL);//保证顺序表的头结点存在

	//1.如果栈还有空间,则将值val插入到top指向的格子里面
	if(Is_Full(st))//判断是否栈满
	{
		Inc(st);//满了就扩容
	}
	//当上面的if执行结束,可以保证现在肯定有空闲格子了

	st->base[st->top] = val;

	//2.注意:不要忘记让top++
	st->top++;

	return true;
}
bool Is_Full(struct Stack *st)
{
	//assert
	//当当前有效格子数 == 当前总格子数,则满了

	return st->top == st->stack_size;
}

//扩容 *2
void Inc(struct Stack *st)
{
	ELEM_TYPE *tmp = (ELEM_TYPE*)realloc(st->base, (st->stack_size * sizeof(ELEM_TYPE))*2);
	if(tmp == NULL)
	{
		printf("error\n");
		return;
	}
	st->base = tmp;

	//st->top;//扩容成功。有效长度不变
	st->stack_size *= 2; 
}

 

这里的重点时 判断是否为满 和 要对top进行 ++ 操作

还有 就是 在我们使用realloc进行扩容的时候 我们要使用另外一个变量来代替 base 然后 如果扩容成功的话 再将其赋值给base 这样可以防止 扩容失败影响栈中元素 完成扩容后要改变 最大空间的大小

出栈

bool Pop(struct Stack *st)
{
	//0.安全性处理
	//1.删除需要判空

	st->top--;
	return true;
}
bool Is_Empty(struct Stack *st)
{
	//0.安全性处理
	return st->top==0;
}

这里的安全性处理 就是 assert 防止这个栈不存在 

然后判空 就是 调用判空函数 来检查是否为空

然后就是在栈中 相对来说 比较特殊的函数 

获取栈顶元素 

那么 或者获取栈顶元素 只是获取并不删除

因此获取完之后不需要进行top--操作

ELEM_TYPE Top(struct Stack *st)
{
	//0.安全性处理
	//1.判空

	return st->base[st->top-1];
}

 搜索函数 是循环遍历这个栈即可

int Search(struct Stack *st, ELEM_TYPE val)
{
	//0.安全性处理
	for(int i=0; i<st->top; i++)
	{
		if(st->base[i] == val)
		{
			return i;
		}
	}
	return -1;
}

最后是清空和打印函数

void Clear(struct Stack *st)
{
	//0.安全性处理

	st->top = 0;
}

//销毁
void Destroy(struct Stack *st)
{
	free(st->base);
	st->stack_size = st->top = 0;
}

//打印
void Show(struct Stack *st)
{
	//0.安全性处理
	for(int i=0; i<st->top; i++)
	{
		printf("%d ", st->base[i]);
	}
	printf("\n");
}

//获取有效值个数
int Get_length(struct Stack *st)
{
	return st->top;

	/*int count = 0;
	for(int i=0; i<st->top; i++)
	{
		count++;
	}
	return count;*/
}

完整代码

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "Stack.h"

//初始化
void Init_stack(struct Stack *st)
{
	st->base = (ELEM_TYPE*)malloc(STACK_INIT_SIZE * sizeof(ELEM_TYPE));
	st->top = 0;//即代表下一个合适的插入位置下标为0,也代表当前有效长度为0
	st->stack_size = STACK_INIT_SIZE;
}

//入栈(队尾插入)
bool Push(struct Stack *st, ELEM_TYPE val)
{
	//0.安全性处理
	assert(st != NULL);//保证顺序表的头结点存在

	//1.如果栈还有空间,则将值val插入到top指向的格子里面
	if(Is_Full(st))//判断是否栈满
	{
		Inc(st);//满了就扩容
	}
	//当上面的if执行结束,可以保证现在肯定有空闲格子了

	st->base[st->top] = val;

	//2.注意:不要忘记让top++
	st->top++;

	return true;
}

//出栈(队尾删除)  出栈,将值删除一个
bool Pop(struct Stack *st)
{
	//0.安全性处理
	//1.删除需要判空

	st->top--;
	return true;
}

//获取栈顶元素值 //获取栈顶的元素值,但是不删除
ELEM_TYPE Top(struct Stack *st)
{
	//0.安全性处理
	//1.判空

	return st->base[st->top-1];
}

//判空
bool Is_Empty(struct Stack *st)
{
	//0.安全性处理
	return st->top==0;
}

//判满
bool Is_Full(struct Stack *st)
{
	//assert
	//当当前有效格子数 == 当前总格子数,则满了

	return st->top == st->stack_size;
}

//扩容 *2
void Inc(struct Stack *st)
{
	ELEM_TYPE *tmp = (ELEM_TYPE*)realloc(st->base, (st->stack_size * sizeof(ELEM_TYPE))*2);
	if(tmp == NULL)
	{
		printf("error\n");
		return;
	}
	st->base = tmp;

	//st->top;//扩容成功。有效长度不变
	st->stack_size *= 2; 
}

//搜索
int Search(struct Stack *st, ELEM_TYPE val)
{
	//0.安全性处理
	for(int i=0; i<st->top; i++)
	{
		if(st->base[i] == val)
		{
			return i;
		}
	}
	return -1;
}

//清空
void Clear(struct Stack *st)
{
	//0.安全性处理

	st->top = 0;
}

//销毁
void Destroy(struct Stack *st)
{
	free(st->base);
	st->stack_size = st->top = 0;
}

//打印
void Show(struct Stack *st)
{
	//0.安全性处理
	for(int i=0; i<st->top; i++)
	{
		printf("%d ", st->base[i]);
	}
	printf("\n");
}

//获取有效值个数
int Get_length(struct Stack *st)
{
	return st->top;

	/*int count = 0;
	for(int i=0; i<st->top; i++)
	{
		count++;
	}
	return count;*/
}

 

 

 

 

 

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

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

相关文章

【Node.js】实现微信小程序在线支付功能

实战项目名称&#xff1a;微信小程序实现在线支付功能 - 文章结尾附上微信小程序码&#xff0c;扫码登录后即可体验&#xff01;&#xff01; 文章目录一、实战步骤1. 前期准备2. 添加wechatpay-node-v3和fs插件3. 预设微信下单的数据4. 将上一步骤的下单信息返回给前端5. 小程…

在抖音全程看世界杯,超高清直播背后的硬实力

导语&#xff1a;IT技术赛场开赛&#xff01;作者 | 宋慧 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;当前&#xff0c;2022 卡塔尔世界杯比赛正在如火如荼进行中&#xff0c;处在更加激烈关键的半决赛阶段。作为足球运动的全球顶级赛事&#xff0c;世界杯…

SysML图例-核聚变

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> [新闻]核聚变里程碑式突破>> SysML图中词汇&#xff1a; Tokamak&#xff1a; 一种利用磁约束来实现受控核聚变的环形容器&#xff0c;通过约束电磁波驱动&#xff…

如何形成前端知识体系

来啦各位大佬&#xff5e;但很不好意思&#xff0c;我就是标题党&#xff0c;这篇博文并没有很明确的给出「如何形成前端知识体系」答案&#xff0c;我自学前端&#xff0c;在面试字节的时候&#xff0c;字节的大佬说我的知识点没有成体系&#xff0c;很零散的飘在各个地方&…

面试官:你如何实现大文件上传

提到大文件上传&#xff0c;在脑海里最先想到的应该就是将图片保存在自己的服务器&#xff08;如七牛云服务器&#xff09;&#xff0c;保存在数据库&#xff0c;不仅可以当做地址使用&#xff0c;还可以当做资源使用&#xff1b;或者将图片转换成base64&#xff0c;转换成buff…

怎么复制网页上不能复制的文字(付费文档免费复制),一招搞定

好多小伙伴上网查资料的时候&#xff0c;想要复制网页内容&#xff0c;但是提示付费复制或者不允许复制&#xff0c;遇到这种情况怎么办呢&#xff1f;下面就是小编分享的一招搞定无法复制网页内容文字的方法。 怎么复制网页上不能复制的文字 借助360安全浏览器/360极速浏览器…

Minecraft 1.19.2 Forge模组开发 06.建筑生成

1.12.2自定义建筑生成 1.16.5自定义建筑生成 1.18.2自定义建筑生成 我们本次尝试在主世界生成一个自定义的建筑。 效果展示效果展示效果展示 由于版本更新缘故&#xff0c;1.19的建筑生成将不涉及任何Java包的代码编写&#xff0c;只需要在数据包中对建筑生成进行自定义。 …

基于粒子群优化算法的BP神经网络预测模型(Matlab代码实现)

目录 1 概述 2 粒子群优化算法 3 BP神经网络 4 PSO优化 BP网络算法 5 运行结果 6 参考文献 7 Matlab代码实现 1 概述 在工程应用中经常会遇到一些复杂的非线性系统,这些系统的状态方程复杂,难以准确的用数学方法建模,而BP神经网络实质上实现了一个从输入到输出的映射功…

【k8s】Kubernetes 基础组件详解

一、k8s简介 Kubernetes 是容器集群管理系统工具&#xff0c;是一个开源平台&#xff0c;可实现容器集群的自动化部署、自动扩缩容、维护等功能。Kubernetesk8s是Kubernetes的缩写&#xff0c;Google 于 2014 年开源了 Kubernetes 项目&#xff0c;Kubernetes的名字来自希腊语&…

无延时直播/超低延时直播实际测试延时效果(项目实测组图)

阿酷TONY / 2022-11-30 / 长沙 / 超多组图 无延时直播/超低延时直播&#xff0c;主要只测试延时情况&#xff0c;没有涉及直播产品的功能、使用操作界面&#xff0c;有兴趣的朋友可以加联系我实际测试哦~~~ 1.无延时直播应用场景 无延时直播/超低延时常见应用场景&#…

近90天互动量破百万,「围炉煮茶」究竟做对了什么?

今年秋冬&#xff0c;“围炉煮茶”爆红网络。小红书相关笔记数量突破8万&#xff0c;累计话题浏览量1200万次&#xff0c;近90天互动量破百万&#xff01; 茶&#xff0c;从老一辈的茶杯茶盘里&#xff0c;通过创新再造&#xff0c;成为年轻人的社交“新”头好。高流量曝光、高…

Go语言性能剖析利器--pprof实战

作者&#xff1a;耿宗杰 前言 关于pprof的文章在网上已是汗牛充栋&#xff0c;却是千篇一律的命令介绍&#xff0c;鲜有真正实操的&#xff0c;本文将参考Go社区资料&#xff0c;结合自己的经验&#xff0c;实战Go程序的性能分析与优化过程。 优化思路 首先说一下性能优化的…

什么是文档管理?

什么是文档管理&#xff1f; 文档管理是指在公司或组织内部组织、存储和检索文档以及自动化工作流程所需的流程和资源。文档可以是硬拷贝或数字格式&#xff0c;包括合同、表单、发票、工作申请、福利登记信息和其他记录。 强大的文档管理的重要性 平均而言&#xff0c;由于…

Web实时预览 界面组件Telerik——提高开发者工作效率的完美组合

Telerik DevCraft包含一个完整的产品栈来构建您下一个Web、移动和桌面应用程序。它使用HTML和每个.NET平台的UI库&#xff0c;加快开发速度。Telerik DevCraft提供最完整的工具箱&#xff0c;用于构建现代和面向未来的业务应用程序。 Telerik ASP.NET AJAX (Web Forms) 组件在…

SAP ABAP OAOR SBDSV1新建BDS类/DOI大数据量输出EXCEL时错误空白或不完整

SAP ABAP OAOR SBDSV1新建BDS类/ DOI大数据量输出 EXCEL时错误空白或不完整 引言&#xff1a; 今日回顾 DOI 使用过程中的两个问题&#xff0c;第一个是管理性问题&#xff08;新建 BDS 类&#xff09;&#xff0c;第二个是技术性问题&#xff08; DOI 大数据量输出 EXCEL 时错…

数据对接:从Notion Database到低代码平台app

前言 Notion简介 近几年&#xff0c;有一款叫Notion的产品异常火爆&#xff0c;它是集笔记、任务管理、Wiki、数据管理为一体的产品&#xff0c;他主打两个理念「模块化」和「All-in-one」&#xff0c;Notion最有魅力的还是引进了Database和双向链的理念 Notion也算是一个渐…

美丽田园通过聆讯:上半年期内利润下降近80% 演员刘涛代言

雷递网 雷建平 12月13日由演员刘涛代言的美丽田园医疗健康产业有限公司&#xff08;简称&#xff1a;“美丽田园”&#xff0c;Beauty Farm&#xff09;日前通过聆讯&#xff0c;准备在港交所上市。上半年期内利润下降近80%美丽田园首家门店1993年成立&#xff0c;至今美丽田园…

C++ Reference: Standard C++ Library reference: Containers: map: map: operators

C官网参考链接&#xff1a;https://cplusplus.com/reference/map/map/operators/ 函数 <map> std::relational operators (map) (1) template <class Key, class T, class Compare, class Alloc> bool operator ( const map<Key,T,Compare,Alloc>&…

记cf一些可能被hack的写法

1. unordered_map 现象 之前经常当O(1)用&#xff0c;作为一些卡常题的必备杀器&#xff0c; 而且&#xff0c;有的hdu/lc题不用umap的话&#xff0c;就只能手写哈希 但是&#xff0c;上次cf里写了个umap被卡了&#xff0c; 这才意识到之前看到的博客不是无稽之谈 其实我…

面试官:单体架构怎么向分布式微服务架构演变的?(8000字)

随着网站规模越来越大&#xff0c;单体应用往往很难再满足要求&#xff0c;就需要向分布式&#xff0c;微服务架构演变。 那么这个演变过程是怎么样的呢&#xff1f;都涉及到哪些组件&#xff0c;会遇到哪些问题&#xff0c;以及相应的解决方案都是什么&#xff0c;本篇文章就来…