【c语言数据结构】栈的详解! 超级详细!(模拟实现,OJ练习题)

news2024/11/17 3:28:17

栈的概念:


栈:像是一种容器,东西只能从一个地方进,一个地方出,且后进先出!这是其和队列(先进先出,像排队一样,先到先得)的本质区别

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

入栈:插入数据在栈顶。

出栈:栈的删除操作。出数据也在栈顶。

栈的模拟实现

Stack.h

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


//定义栈的结构
typedef int STDataType;
typedef struct Stack
{
    STDataType* arr;
    int capacity;//栈的空间大小
    int top;//栈顶(插入数据和删除数据的位置)
}ST;

//初始化
void STInit(ST* ps);//传的是地址

//销毁
void STDestory(ST* ps);

//栈顶-=--如数据、出数据

//栈的入数据操作
void SrackPush(ST* ps, STDataType x);//第二个参数是要插入的数据

//栈的出数据操作
void SrackPop(ST* ps);

//取栈顶元素---循环打印栈顶的数据
STDataType StackTop(ST* ps);//返回值是栈顶的元素

//判断栈是否为空
bool StackEmpty(ST* ps);

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

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//初始化
void STInit(ST* ps) {
	assert(ps);//看文件是不是传空
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
	//初始的栈顶和栈底都为0(栈为空)
}

//销毁
void STDestory(ST* ps) {
	assert(ps);
	if (ps->arr != NULL) //栈不为空,说明里面有数据占用空间,直接将其释放掉

	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

//栈顶-=--如数据、出数据
//入栈要判断空间是否满了(满了就没法加入数据了)
//出栈,取栈顶元素都要判断栈是否为空(空的栈你能取啥玩意啊)

//栈的入数据操作
void SrackPush(ST* ps, STDataType x) {
	assert(ps);

	//先判断空间情况,还能否加入数据!!!!!!!!!!
	if (ps->top == ps->capacity)//空间满了,需要增容
	{
		//一般情况是二倍的增加
		//初始情况下我们的capacity是定义为0的,所以我们不能直接进行乘二的操作
		//我们需要创建一个变量newCapacity
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType*));
		if (tmp == NULL) {
			perror("realloc fail!");
			exit(1);
		}

		//申请成功,将tmp申请的空间给pa->arr
		ps->arr = tmp;
		ps->capacity = newCapacity;//容量增加
	}

	//到此为止,空间够够的了,可以放入数据了
	//往栈顶添加数据
	ps->arr[ps->top++] = x;
}



//判断栈是否为空
bool StackEmpty(ST* ps) {
	assert(ps);
	//return ps->arr == NULL;这是判断指针是否为空
	return ps->top == 0;
}
	//栈的出数据操作
void SrackPop(ST* ps) {
	assert(ps);
	//要判断是否栈为空!!!不然空栈怎么出数据!
	assert(!StackEmpty(ps));

	//走到这里就说明栈不为空
	--ps->top;//我们只需要将top进行--操作就能进行栈的出数据操作了
}

栈的出数据操作
//void SrackPopError(ST* ps) {
//	assert(ps);
//	return --ps->arr[ps->top];
//}




//取栈顶元素---循环打印栈顶的数据
STDataType StackTop(ST* ps) {
	assert(ps);
	assert(!StackEmpty(ps));//判断当前栈是不是空的,如果是空的话,我们没有什么能取的
	return ps->arr[ps->top-1];//类似数组,最后一个数据是top-1下标
}



//获取栈中有效个数
int STSize(ST* ps) {
	assert(ps);
	return ps->top;
}

栈的相关OJ练习题

有效的括号

思路:

①用指针ps遍历括号字符串

②ps遇到左括号->入栈,ps++继续向下走

    ps遇到右括号->在栈顶的左括号比较是否匹配

③两者匹配->出栈,ps++继续向下走,直至全部匹配,返回true

    两者不匹配->非有效括号,返回false,栈销毁

代码及解析

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//定义栈的结构
typedef char STDataType;
typedef struct Stack
{
	STDataType* arr;
	int capacity;//栈的容量
	int top;//栈顶
}ST;

//初始化
void STInit(ST* ps) {
	assert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}
//销毁
void STDestory(ST* ps) {
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;

}

//栈顶-=--如数据、出数据

//栈的入数据操作
void StackPush(ST* ps, STDataType x) {
	assert(ps);
	//判断空间是否已满
	if (ps->capacity == ps->top) {
		int newCapacity = ps->capacity == 0 ? 4 : 2 * (ps->capacity);
		STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType*));
		if (tmp == NULL) {
			perror("realloc fail!");
			exit(1);
		}

		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
	ps->arr[ps->top++] = x;
}

//判断栈是否为空
bool StackEmpty(ST* ps) {
	assert(ps);
	return ps->top == 0;
}
//栈的出数据操作
void StackPop(ST* ps) {
	assert(ps);
	//判断数据是否为空
	assert(!StackEmpty(ps));

	--ps->top;
}

//取栈顶元素---循环打印栈顶的数据
STDataType StackTop(ST* ps) {
	assert(ps);
	assert(!StackEmpty(ps));

	return ps->arr[ps->top - 1];
}



//获取栈中有效个数
int STSize(ST* ps) {
	assert(ps);
	return ps->top;
}

bool isValid(char* s) {
	//创立新的栈
	ST S;
	//初始化
	STInit(&S);

	//取字符指针遍历括号字符串
	char* ps = s;
	while (*ps != '\0') {
		//判断是否是左括号,是->入栈
		if (*ps == '(' || *ps == '[' || *ps == '{') {
			StackPush(&S,*ps);
		}
		else//此时的ps是右括号->比较匹配左括号
		{
			//因为可能拿了左括号没有右括号,得先判断此时栈是否为空
			if (StackEmpty(&S))
				return false;
			//取目前栈顶的左括号保存在ch中,方便比较
			char ch = StackTop(&S);
			//若匹配
			if ((*ps == ')' && ch == '(') || (*ps == ']' && ch == '[') || (*ps == '}' && ch == '{')) {
				//将第一个栈顶左括号出栈
				StackPop(&S);
			}
			else//不匹配,是无效括号,直接返回错误
			{
				STDestory(&S);//返回前记得销毁
				return false;
			}
		}
		ps++;
	}
	bool ret = StackEmpty(&S) == true;//为空->全匹配完了->返回true
	//销毁
	STDestory(&S);
	return ret;
}

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

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

相关文章

“JY901传感器“学习笔记

目录 一、产品概述 二、产品功能介绍 2.1、轴向说明 2.2、模块校准 2.3、姿态角 2.4、大地坐标系、地心地固坐标系、站心坐标系 三、参考文献 一、产品概述 模块集成高精度的陀螺仪、加速度计、地磁场传感器&#xff0c;采用高性能的微处理器和先进的动力解算与卡尔曼动…

两种不同方式实现交换机路由器的登录Console+Telnet的实现

一、背景及原理 1.Telnet 作为一种远程登录协议,1969年发明诞生于美国国防部高级研究计划局网络工作小组的研究员,Tenlet的出现为后续相关技术的发展奠定了基础。 2.Telnet通常用于远程登录应用中,对本地和远端进行网络设备配置、监控、维护,可以通过Telnet方式在一台设备…

博睿数据受邀亮相NebulaGraph Meetup北京站

9 月 21 日&#xff0c;北京站 nMeetup 如期而至&#xff0c;一场以 GraphRAG 和人工智能技术融合为主题的开发者聚会&#xff0c;在金秋的首都拉开帷幕。8 位讲师和 140 多位来自五湖四海的行业伙伴们相聚一堂&#xff0c;共同探讨 GraphRAG & AI 的最新发展和应用实践&am…

卷轴模式:一种新型的电子商务营销策略

随着电子商务行业的蓬勃发展&#xff0c;各类创新营销策略层出不穷&#xff0c;旨在吸引更多消费者并提升销售额。在这之中&#xff0c;卷轴模式以其独特的优势和可观的收益逐渐受到业界renxb001的关注。本文将深入探讨卷轴模式的概念、优势、应用场景以及如何参与其中。 卷轴…

关联式容器——map与set

map与set map与set的使用序列式容器与关联式容器概念序列式容器 (Sequence Containers)常见的序列式容器&#xff1a; 关联式容器 (Associative Containers)常见的关联式容器&#xff1a; set的定义与使用set类的介绍set的构造和迭代器set的增删查&#xff08;无改&#xff09;…

Ego微商小程序项目实战4.0【环境搭建】

✨博客主页&#xff1a; https://blog.csdn.net/m0_63815035?typeblog &#x1f497;《博客内容》&#xff1a;.NET、Java.测试开发、Python、Android、Go、Node、Android前端小程序等相关领域知识 &#x1f4e2;博客专栏&#xff1a; https://blog.csdn.net/m0_63815035/cat…

自动化测试框架集成:将Selenium集成到pytest与unittest中

目录 引言 一、Selenium简介 二、Selenium与pytest的集成 1. 安装pytest和Selenium 2. 编写测试用例 3. 运行测试 三、Selenium与unittest的集成 1. 编写测试类 2. 运行测试 四、Selenium自动化测试的最佳实践 1. 使用Page Object模式 2. 合理利用等待机制 3. 跨浏…

vioovi视与视标准工时工具与ECRS工时分析软件:精益生产的新纪元

在当今快速变化的市场环境中&#xff0c;企业面临着前所未有的挑战&#xff0c;其中成本控制与效率提升成为制约其发展的关键因素。传统的标准工时工具在应对这些挑战时显得力不从心&#xff0c;其局限性日益凸显。而vioovi视与视标准工时工具的出现&#xff0c;则为企业实现精…

西门子触摸屏下载时提示缺少面板映像的解决方法汇总

西门子触摸屏下载时提示缺少面板映像的解决方法汇总 使用V15/V15.1/V16/V17/V18/V19下载精智(Comfort)系列屏的项目时有时会提示“由于缺少面板映像,下载失败。请安装缺少的面板映像”,造成上述异常的主要原因是V15/V15.1/V16/V17/V18/V19的软件缺少对应的映像文件。常见问题…

《Linux从小白到高手》开篇:脱胎换骨之为什么要深度学习Linux?

List item 这一篇字数比较多&#xff0c;可能会比较枯燥。但是&#xff0c;如果你想学习Linux或者你想进一步提升自己的Linux专业水平&#xff0c;那么&#xff0c;还是请你坚持看完。这倒不是说文笔有多好&#xff0c;而是作为一个学习并使用了Linux 十多年的老司机&#xff…

PHP Swoole 基本使用

背景 在项目中&#xff0c;我们使用了PHP语言&#xff0c;但由于存在长耗时的任务&#xff0c;所以需要服务器端异步响应。为了实现异步响应&#xff0c;我们有多种方案可选&#xff0c;包括MQ&#xff08;消息队列&#xff09;、fsocket&#xff08;文件套接字&#xff09;、…

【Redis】渐进式遍历 数据库管理命令 RESP协议

目录 渐进式遍历 scan 数据库管理命令 切换数据库 获取当前数据库key的个数 删除当前数据库所有的key 删除所有数据库中所有的key RESP协议 渐进式遍历 Redis使用scan命令进行渐进式遍历键&#xff0c;进而解决直接使用keys获取键时可能出现的阻塞问题&#xff08;因为…

多旋翼无人机光伏发电站吊运技术详解

随着清洁能源技术的快速发展&#xff0c;光伏发电站作为可再生能源的重要组成部分&#xff0c;其建设与维护对效率、安全性和成本控制的要求日益提高。多旋翼无人机光伏发电站吊运技术应运而生&#xff0c;该技术利用多旋翼无人机强大的垂直起降能力、灵活的飞行控制以及高效的…

CSS中的字体样式、文本样式、列表样式以及背景和渐变

一、字体样式和文本样式 1.span标签 span标签的作用&#xff1a;能让某几个文字或者是词语凸显出来 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-…

【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)详细理解并附实现代码。

【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU) 【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU) 文章目录 【深度学习基础模型】门控循环单元 (Gated Recurrent Units, GRU)1.门控循环单元 (Gated Recurrent Units, GRU) 原理详解1.1 GRU 概…

一个任务的一辈子

总览 孕育&#xff1a;这一步是生命的起源&#xff0c;对应"任务"就是&#xff1a;申办人因为办理业务而发起一个流程。这是任务产生的摇篮。 任务的使命就是为了完成业务;生产&#xff1a;这是新生命产生的过程&#xff0c;对应"任务"就是&#xff1a;任务…

IT运维挑战与对策:构建高效一体化运维管理体系

在当今数字化时代&#xff0c;IT运维作为企业运营的核心支撑&#xff0c;其重要性不言而喻。然而&#xff0c;随着业务规模的扩大和技术的不断革新&#xff0c;IT运维团队面临着前所未有的挑战。本文旨在深度剖析当前IT运维中存在的主要问题&#xff0c;并探索一体化解决方案&a…

1500PLC使用EPOS控制伺服电机

硬件配置与参数 硬件配置 名称 型号 数量 PLC 1512C-1 PN 1个 伺服放大器 V90 PN 1个 伺服电机 SIMOTICS 1个 V90 PN伺服驱动器&#xff1a; 伺服驱动器硬件参数 使用软件&#xff1a;V-ASSISTANT 软件连接时可选择USB连接或者Ethernet连接&#xff0c;根据实际…

【ComfyUI】生成图细节更清晰——Consistency_Decoder

原文&#xff1a;https://github.com/openai/consistencydecoder comfyui: https://github.com/gameltb/Comfyui_Consistency_Decoder_VAE 博文资料下载&#xff1a;https://pan.baidu.com/s/1SwfA4T6iMsA8IrRrGXm4sg?pwd0925 安装 【秋葉aaaki】comfyui一键运行包 夸克网盘…

Vue下载静态文件

1、需求&#xff1a;将静态文件放在本地&#xff0c;让用户进行下载。 2、文件位置&#xff1a; ① 原生js&#xff1a;直接将文件放在某个目录或者根目录下 ② Vue&#xff1a;将文件放在根目录的public文件夹下面 3、代码示例&#xff1a; const url "/模板.xlsx"…