栈(基于动态顺序表实现的栈)

news2025/2/25 2:22:02

栈的简单介绍

关于栈的性质咳咳

栈:栈是一种特殊的线性表,其中只让在一端插入和删除元素。

后进先出

进行插入删除的那一端叫栈顶,另一端叫栈底

我们实现的栈是基于一个动态顺序表的的栈,会实现栈的   入栈,出栈,获取栈顶元素,获取栈中元素个数,判断栈是否为空(纯c语言版本)

操作的命名如下

栈的信息

这是栈的信息,

接下来初始化

我们在创建好栈的信息后定义一个栈,然后进行初始化,初始时我们可以让栈中放4个元素,在开一段可以放入4个元素的内存,让a指向

初始化

初始化要用到的函数malloc,这个不懂的可以看这个

动态内存管理()-CSDN博客

在我们开空间的化可能会开失败,如果开失败的化,直接把返回的指针给ps->a程序会出现内存问题,所以我们创建一个临时变量,存放新开空间首位置的指针,如果这个指针不为空,就把临时的tmp指针给ps->a。这个操作在后续操作用到,比如在入栈时栈满,我们还要进行一次扩容,所以我们可以写一个扩容函数

入栈

代码如下

判空

判空这个操作实现的功能是如果这个栈里面没有元素的化返回假,有元素返回真

在  Stack.h 中加入#include<stdbool.h>   就可以用布尔类型了,我们的栈中的top

真好就是栈中元素的真是个数-1,因为top,从0开始就有元素了,所以返回 top+1;即可

代码如下

出栈

我们判空操作实现后就方便出栈了

在出栈时需要考虑一个栈是否为空的情况所以直接调用上面的函数特判一下,不为空让top--,就可以了

代码

获取栈顶元素

判断一下不是空,然后返回栈中top指向的元素,代码如下

woc,怎末感觉突然没话讲了,

获取栈中元素个数,栈的销毁

完整的代码


//Stack.h

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
#include<assert.h>
#include<windows.h>


//栈的元素类型
typedef int STaType;


typedef struct Stack
{
	STaType* a;
	int top;//栈顶
	int capacity;//栈满容量
}Stack;


//栈的打印
void Stack_print(Stack p);
//栈中元素的输入
void Stack_scan(STaType* x);
//扩容
void Stack_Check();
//初始化
void Stack_Lnit(Stack* ps);
//入栈,出栈
void Stack_push(Stack* ps, STaType x);
void Stack_pop(Stack* ps);
//获取栈顶元素
STaType Stack_top(Stack* ps);
//获取栈内元素个数
int Stack_size(Stack* ps);
//判空
bool Stack_empty(Stack* ps);
//销毁
void Stack_Destroy(Stack* ps);

//Stack.c

#include"Stack.h"

//typedef struct Stack
//{
//	STaType* a;
//	int top;//栈顶
//	int capacity;//栈满容量
//}Stack;


//栈的打印
void Stack_print(Stack p)
{
	printf("\n现在栈如下\n");

	while (p.top != -1)
	{
		printf("%d\n", p.a[p.top]);
		p.top--;
	}
	printf("\n");
	printf("\n");
}

//栈中元素的输入
void Stack_scan(STaType* x)
{
	scanf("%d", x);
}

//扩容
void Stack_Check(Stack*ps)
{
	assert(ps);
	int x = ps->capacity==0?4:ps->capacity*2;
	if (ps->top == ps->capacity)
	{
		STaType* tmp = (STaType*)malloc(sizeof(STaType)*x);
		assert(tmp);
		ps->a = tmp;
	}
	ps->capacity = x;
}


//初始化
void Stack_Lnit(Stack* ps)
{
	assert(ps);

	ps->capacity = 4;
	ps->top = -1;//栈顶有元素
	STaType *tmp= (STaType*)malloc(sizeof(STaType)*ps->capacity);
	if (tmp != NULL)
		ps->a = tmp;
}

//入栈,出栈
void Stack_push(Stack* ps, STaType x)
{
	assert(ps);
	Stack_Check(ps);//判断扩容
	ps->a[++ps->top] = x;
}


void Stack_pop(Stack* ps)
{
	assert(ps);
	if(!Stack_empty(ps))
		ps->top--;
	else
	{
		printf("栈为空,出栈失败\n");
		return;
	}
}

//获取栈顶元素
STaType Stack_top(Stack* ps)
{
	assert(ps);
	if (Stack_empty(ps))
	{
		printf("栈为空,出栈失败\n");
		return 0;
	}
	return ps->a[ps->top];
}

//获取栈内元素个数
int Stack_size(Stack* ps)
{
	assert(ps);
	return ps->top + 1;
}

//判空
bool Stack_empty(Stack* ps)
{//为空返回真,不为空返回假
	assert(ps);
	return ps->top == -1;
}


//销毁
void Stack_Destroy(Stack* ps)
{
	if (ps->a)
	{
		free(ps->a);
	}
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}



//Text.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

void enumm()
{
	printf("********************************************************************\n");
	printf("********************************************************************\n");
	printf("********************************************************************\n");
	printf("********************************************************************\n");
	printf("**1  初始化                           2.入栈                                 **************\n");
	printf("**3  出栈                           4.获取栈顶元素                   **************\n");
	printf("**5  获取栈中元素个数       6判空                                 **************\n");
	printf("**7  销毁栈                        0退出                                 **************\n");
	printf("********************************************************************\n");
	printf("*******************************************************************\n");
	printf("********************************************************************\n");
}

void text()
{
	Stack pp;
	enumm();
	do
	{
		int po; scanf("%d", &po);
		switch (po)
		{
		case 1://创
			Stack_Lnit(&pp);
			break;
		case 2://入栈
			STaType x;
			Stack_scan(&x);
			Stack_push(&pp, x);
			Stack_print(pp);
			break;
		case 3://出栈
			Stack_pop(&pp);
			Stack_print(pp);
			break;
		case 4://获取栈顶元素
			STaType xx= Stack_top(&pp);
			printf("%d", xx);
			break;
		case 5://获取栈中元素个数
			int n = Stack_size(&pp);
			printf("%d", n);
			break;
		case 6://判空
			if (!Stack_empty(&pp)) printf("不是空\n");
			else printf("是空\n");
			break;
		case 7://销毁栈
			Stack_Destroy(&pp);
		case 0://退出
			goto xxx;
			break;
		}
		//system("cls");
	} while (1);
xxx:;

}

signed main()
{
	text();
	getchar();
	return 0;
}

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

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

相关文章

【NumPy】关于numpy.eye()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

15:00面试,15:08就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

【重学C++】02 脱离指针陷阱:深入浅出 C++ 智能指针

前言 大家好&#xff0c;今天是【重学C】系列的第二讲&#xff0c;我们来聊聊C的智能指针。 为什么需要智能指针 在上一讲《01 C如何进行内存资源管理》中&#xff0c;提到了对于堆上的内存资源&#xff0c;需要我们手动分配和释放。管理这些资源是个技术活&#xff0c;一不…

Thinkphp内核开发盲盒商城源码v2.0 对接易支付/阿里云短信/七牛云存储

源码简介 这套系统是我从以前客户手里拿到的,100完整可用,今天测试防红链接失效了,需要修改防红API即可!前端页面展示我就不放了,懂的都懂 优点是Thinkphp开发的&#xff0c;二开容易。 源码图片 资源获取&#xff1a;Thinkphp内核开发盲盒商城源码v2.0 对接易支付/阿里云短…

浅谈hook下的免杀研究

文章目录 前记实现过程后记reference 前记 原理 CS在高版本中推出了sleep mask功能&#xff0c;即在beacon sleep时对堆进行加密混淆&#xff0c;绕过内存扫描&#xff0c;在恢复运行前还原&#xff0c;防止进程崩溃。beacon每次运行的时间远短于sleep时间&#xff0c;内存扫描…

python实现520表白图案

今天是520哦&#xff0c;作为程序员有必要通过自己的专业知识来向你的爱人表达下你的爱意。那么python中怎么实现绘制520表白图案呢&#xff1f;这里给出方法&#xff1a; 1、使用图形库&#xff08;如turtle&#xff09; 使用turtle模块&#xff0c;你可以绘制各种形状和图案…

GPT‑4o普通账户也可以免费用

网址 https://chatgpt.com/ 试了一下&#xff0c;免费的确实显示GPT‑4o的模型&#xff0c;问了一下可以联网&#xff0c;不知道能不能通过插件出图 有兴趣的可以试试

海山数据库(He3DB)代理ProxySQL使用详解:(一)架构说明与安装

一、ProxySQL介绍 1.1 简介 业界比较知名的MySQL代理&#xff0c;由ProxySQL LLC公司开发并提供专业的服务支持&#xff0c;基于GPLv3开源协议进行发布,大部分配置项可动态变更。后端的MySQL实例可根据用途配置到不同的hostgroup中&#xff0c;由ProxySQL基于7层网络协议,将来…

第二证券股市资讯:突传重磅!高盛最新发声,事关中国股票!

外资猛买我国财物。 高盛在最新发布的陈述中称&#xff0c;海外对冲基金已连续第四周增持我国股票。另据彭博社的数据显现&#xff0c;上星期&#xff0c;我国是新式商场国家中录得最大资金流入的商场&#xff0c;达4.88亿美元&#xff08;约合人民币35亿元&#xff09;。 北…

滴滴三面 | Go后端研发

狠狠的被鞭打了快两个小时… 注意我写的题解不一定是对的&#xff0c;如果你认为有其他答案欢迎评论区留言 bg&#xff1a;23届 211本 社招 1. 自我介绍 2. 讲一个项目的点&#xff0c;因为用到了中间件平台的数据同步&#xff0c;于是开始鞭打数据同步。。 3. 如果同步的时候…

OpenFeign高级用法:缓存、QueryMap、MatrixVariable、CollectionFormat优雅地远程调用

码到三十五 &#xff1a; 个人主页 微服务架构中&#xff0c;服务之间的通信变得尤为关键。OpenFeign&#xff0c;一个声明式的Web服务客户端&#xff0c;使得REST API的调用变得更加简单和优雅。OpenFeign集成了Ribbon和Hystrix&#xff0c;具有负载均衡和容错的能力&#xff…

LInux实验二--进程间通信--信号

一、实验原理&#xff1a; 信号类似 windows 下的消息,用于通知进程有某种事件发生。只要知道进程的进 程号,就可以向进程发送信号。而进程可以自行定义对信号的处理方法。 二、实验内容&#xff1a; 实例一&#xff1a;编写实例&#xff0c;让子进程在启动2s后杀死父进程 /…

Docker Portainer使用

Portainer是什么 Docker Portainer是一个轻量级的 Web UI 管理界面,可以用来管理Docker环境。它提供了一个直观的控制台,用户可以通过它来管理Docker主机、容器、网络、卷等Docker资源。 Portainer的主要功能和特点包括: 容器管理:可以查看、启动、停止、删除容器,以及查看容器…

跳过无限debugger实战——替换和条件断点实战

网址&#xff1a;Scrape | Movie 打卡开发者工具&#xff1a; debugger代码及含义 setInterval((function() {debugger ;console.log("debugger")} function()是要执行的函数。interval是每次执行之间的时间间隔&#xff0c;以毫秒为单位。 你可以用想要的时间间隔…

用C语言把一棵普通二叉树安排得明明白白

1. 树的相关术语 结点的度&#xff1a;一个结点含有的子树的个数称为该结点的度&#xff1b; 如上图&#xff1a;A的为6 叶结点或终端结点&#xff1a;度为0的结点称为叶结点&#xff1b; 如上图&#xff1a;B、C、H、I...等结点为叶结点 非终端结点或分支结点&#xff1a;度不…

linux与windows脚本格式必须转换,linux只有LF

如果windows下的脚本在linux下直接执行&#xff0c;则会造成无穷的错误。 在文本处理中, CR, LF, CR/LF是不同操作系统上使用的换行符. Dos和windows&#xff1a; 采用回车换行CR/LF表示下一行. UNIX/Linux &#xff1a; 采用换行符LF表示下一行. MAC OS &#xff1a; 采用回车…

Git提交和配置命令

一、提交代码到仓库 在软件开发中&#xff0c;版本控制是一个至关重要的环节。而Git作为目前最流行的版本控制系统之一&#xff0c;为我们提供了便捷高效的代码管理和协作工具。在日常开发中&#xff0c;我们经常需要将本地代码提交到远程仓库&#xff0c;以便于团队协作和版本…

c++笔记3

优先队列 普通的队列是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。优先队列是一种按照优先级决定出队顺序的数据结构&#xff0c;优先队列中的每个元素被赋予级别&#xff0c;队首元素的优先级最高。 例如&#xff1a;4入队&#xff0c…

142.栈和队列:用栈实现队列(力扣)

题目描述 代码解决 class MyQueue { public:stack<int> stIn; // 输入栈&#xff0c;用于push操作stack<int> stOut; // 输出栈&#xff0c;用于pop和peek操作MyQueue() {}void push(int x) {stIn.push(x); // 将元素压入输入栈}int pop() {// 如果输出栈为空&…

如何*永久*禁用edge打开PDF文件?

要永久禁用Microsoft Edge打开PDF文件&#xff0c;您可以按照以下步骤进行操作&#xff1a; 打开文件资源管理器并找到任意一个PDF文件。 右键单击该文件并选择“属性”。 在“属性”对话框中&#xff0c;单击“更改”按钮旁边的“打开方式”。 在“打开方式”对话框中&…