【数据结构初阶】深度理解 “栈” (附源码)

news2024/11/15 10:35:49

hello,又见面了!

目录

1.  栈的概念与结构

2、栈的实现

Stack.h

Stack.c

test.c

3、习题


正文开始——

1.  栈的概念与结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守先进后出的原则。

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

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

【图解】

栈的底层结构

内存比较:双向链表比单链表多了一种指针,内存占用就相对多一些;数组和单链表,数组每次都以2倍大小增容,正因如此,无需多次增容,而单链表每次增加数据都要申请空间,删除数据要释放空间,较为繁琐。

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

2、栈的实现

栈里的数据不能被遍历,不能被随机访问。每次取数据只能取栈顶数据

Stack.h

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

//定义栈的结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* arr;
	int capacity;  //栈的容量
	int top;       //栈顶
}ST;

//初始化
void STInit(ST* ps);

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

//入数据
void StackPush(ST* ps, STDataType x);

//出数据
void StackPop(ST* st);

//取栈顶元素
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;  //此时栈为空,栈顶=栈底
}

//销毁
void STDestroy(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 file!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
	//空间足够
	ps->arr[ps->top++] = x;
}

//出数据
void StackPop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

	ps->top--;
}

//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

//取栈顶元素
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(!StackEmpty(ps));

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

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

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"

void STTest()
{
	ST st;
	STInit(&st);

	StackPush(&st,1);
	StackPush(&st,2);
	StackPush(&st,3);
	StackPush(&st,4);
	StackPush(&st,5);
	printf("size:%d\n", STsize(&st));
	/*StackPop(&st);*/

	//循环出栈,直到栈为空
	while (!StackEmpty(&st))
	{
		STDataType data = StackTop(&st);
		printf("%d ", data);
		//出栈
		StackPop(&st);
	}
	printf("size:%d\n", STsize(&st));

	STDestroy(&st);
}

int main()
{
	STTest();
	return 0;
}

3、习题

【思路】 


//定义栈的结构
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 STDestroy(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 file!");
			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];
}

bool isValid(char* s) {
    ST st;
    STInit(&st);
    char* ps=s;
    while(*ps!='\0')
    {
        //左括号,入栈
        if(*ps=='('||*ps=='['||*ps=='{')
        {
            StackPush(&st,*ps);
        }
        else  //右括号,与栈顶元素判断是否匹配,匹配,出栈,不匹配,返回false
        {
            if(StackEmpty(&st))
            {
                STDestroy(&st);
                return false;
            }
            char ch=StackTop(&st);
            if(*ps==')'&&ch=='('||*ps=='}'&&ch=='{'||*ps==']'&&ch=='[')
            {
                StackPop(&st);
            }
            else
            {
                STDestroy(&st);
                return false;
            }
        }
        ps++;
    }
    bool ret=StackEmpty(&st)==true;
    STDestroy(&st);
    return ret;
}

至此,栈,结束——


完——

最好的安排_曲婉婷_高音质在线试听_最好的安排歌词|歌曲下载_酷狗音乐酷狗音乐为您提供由曲婉婷演唱的高清音质无损最好的安排mp3在线听,听最好的安排,只来酷狗音乐!icon-default.png?t=N7T8https://t3.kugou.com/song.html?id=Ykfb93CQV2

至此结束——

我是云边有个稻草人

期待与你的下一次相遇 !

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

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

相关文章

小试牛刀-Telebot区块链游戏机器人(TS升级)

目录 1.编写目的 2.为什么使用TypeScript实现? 3.实现功能 3.1 AI图片生成 3.2 签到 3.3 邀请 3.4 WalletConnect连接 4.功能实现详解 4.1 AI图片生成 4.2 签到 4.3 邀请 4.4 WalletConnect连接 5.功能截图 ​6.问题整理 Welcome to Code Blocks blog 本篇文章主…

塑造美好心灵,激发创造活力|第三届瓷艺中华“陶溪川杯”儿童青少年陶瓷作品展开展

第三届瓷艺中华“陶溪川杯”儿童青少年陶瓷作品展 展览现场 由中央美术学院、景德镇陶瓷大学、景德镇陶文旅控股集团共同主办&#xff0c;由中国非物质文化遗产保护协会陶瓷分会、中国文化艺术发展促进会陶瓷专业委员会、中央美术学院陶瓷艺术研究院、中央美术学院少儿美术教…

无人机无刷电机技术详解及选型

1. 技术原理 无人机无刷电机&#xff08;Brushless DC Motor, BLDC&#xff09;是现代无人机动力系统的核心部件&#xff0c;其工作原理基于电磁感应和换向技术&#xff0c;实现了无需物理接触即可持续旋转的高效率动力输出。与传统有刷电机相比&#xff0c;无刷电机通过电子换…

你好! Git——如何进行多人协作

多人协作&#xff08;5&#xff09; 一、标签管理二、多人协作2.1 场景一&#xff08;这种方式不常见&#xff09;2.2 场景二&#xff08;常见&#xff09; 一、标签管理 标签 tag &#xff0c;可以简单的理解为是对某次 commit 的⼀个标识&#xff0c;相当于起了⼀个别名。 …

【给嵌入式新人的几条建议(共勉):三-C语言基础怎么补?】

给嵌入式新人的几条建议&#xff08;共勉&#xff09;&#xff1a;三-C语言基础怎么补&#xff1f; 前言1、先回答一个问题&#xff0c;对C语言的害怕到底在哪&#xff1f;&#xff08;纠正认知&#xff09;2、C语言基础&#xff0c;要补全部吗&#xff1f;No2.1 先看下自己属于…

深耕编程语言18年,对话 Rust、TypeScript、Nushell 核心贡献者 Sophia Turner | Open AGI Forum

作者 | Annie Xu 采访 | 卢威 责编 | Echo Tang 出品丨GOSIM 开源创新汇 编程语言的种类令人眼花缭乱&#xff0c;但成功的、常用的编程语言却是凤毛麟角。在深耕编程语言研发 18 年的 Sophia June Turner 看来&#xff0c;编程语言成功的关键在于其研发团队的透明度和机制建…

Azure OpenAI Embeddings vs OpenAI Embeddings

题意&#xff1a;Azure OpenAI 嵌入与 OpenAI 嵌入的比较 问题背景&#xff1a; Is anyone getting different results from Azure OpenAI embeddings deployment using text-embedding-ada-002 than the ones from OpenAI? Same text, same model, and the results are cons…

Learning vtkjs之Calculator

过滤器 公式计算器 Calculator 介绍 The Calculator filter is a fast way to add derived data arrays to a dataset. These arrays can be defined over points, cells, or just field data that is “uniform” across the dataset (i.e., constant over all of space). Va…

【小尘送书-第十六期】码农职场:IT人求职就业手册

大家好&#xff0c;我是小尘&#xff0c;欢迎你的关注&#xff01;大家可以一起交流学习&#xff01;欢迎大家在CSDN后台私信我&#xff01;一起讨论学习&#xff0c;讨论如何找到满意的工作&#xff01; &#x1f468;‍&#x1f4bb;博主主页&#xff1a;小尘要自信 &#x1…

【JVM】垃圾回收机制、算法和垃圾回收器

什么是垃圾回收机制 为了让程序员更加专注于代码的实现&#xff0c;而不用过多的考虑内存释放的问题&#xff0c;所以在Java语言中&#xff0c;有了自动的垃圾回收机制&#xff0c;也是我们常常提及的GC(Garbage Collection) 有了这个垃圾回收机制之后&#xff0c;程序员只需…

华为路由常见 LSA 类型的产生及作用域和字段详细解读

华为路由常见 LSA 类型的产生及作用域 类型名称描述1路由器 LSA&#xff08;Router LSA&#xff09;每个设备都会产生&#xff0c;描述了设备的链路状态和开销。该 LSA 只能在接口所属的区域内泛洪2网络 LSA&#xff08;Network LSA&#xff09;由 DR 产生&#xff0c;描述该 …

在cPanelWHM中如何重置 MySQL 用户帐户密码

更改MySQL用户账户密码非常简单。服务器管理员可以在WHM中编辑任何MySQL用户的帐户。cPanel用户可以编辑其帐户管理的数据库的密码。 在WHM中更改MySQL用户帐户密码 打开WHM&#xff0c;在侧边菜单中的SQL服务下选择“Change MySQLUser Password”。Hostease的服务器产品提供稳…

NeRF学习——复现训练中的问题记录

代码复现的框架是基于&#xff1a;pengsida 的 Learning NeRF 希望各位可以通过学习 NeRF-Pytorch 的源码来自己复现一下试试看&#xff01; 文章目录 1 Windows bug1.1 DataLoader 的多进程 pickle1.2 imageio 输出图片1.3 I/O 2 训练问题2.1 Evaluate 显存爆炸2.2 尝试一2.…

基于VScode和C++实现Protobuf数据格式的通信

目录 1. Protobuf 概述1.1 定义1.2Protobuf的优势 2. Protobuf 语法3、序列号和反序列化3.1 .pb.h 头文件3.2 序列化3.3 反序列化 4、测试用例 Protobuf详细讲解链接 1. Protobuf 概述 1.1 定义 protobuf也叫protocol buffer是google 的一种数据交换的格式&#xff0c;它独立…

递归题解集

目录 递归&#xff1a; 一、汉诺塔问题 1.题目链接&#xff1a;面试题 08.06. 汉诺塔问题 2.题目描述&#xff1a; 3.解法&#xff1a;&#xff08;递归&#xff09; &#x1f335;算法思路&#xff1a; &#x1f335;算法流程&#xff1a; &#x1f335;算法代码&…

掌握SEO站外推广优化的五大绝招

对于网站运营者和数字营销人员来说&#xff0c;SEO站外推广是提升网站流量和排名的重要手段。以下是五个有效的SEO站外推广优化方法&#xff0c;希望对大家有所帮助。 1. 高质量的外链建设 高质量的外部链接&#xff08;Backlinks&#xff09;是搜索引擎排名的重要因素之一。…

Openboxes开发环境配置及本地化、API测试

目录 Openboxes简介 开发环境配置及启动 更新中文多语言配置 API测试 Openboxes简介 Openboxes是一款开源的仓库管理软件&#xff0c;提供了库存管理、采购管理、销售管理等功能&#xff0c;可以帮助用户高效地管理仓库及库存。并提供了丰富的API接口。系统基于java8 和Gr…

关于微信,qq小程序的登录,数据库-前端-接口解析

一、背景 当我们在对接微信平台&#xff0c;开发微信小程序时&#xff0c;用户标识是必不可少的。用户标识贯通了整个开发过程&#xff0c;所以获取到唯一的用户标识是必须的。 二、多平台兼容 因为考虑到一次开发&#xff0c;可多端运行&#xff0c;需要考虑兼容多平台兼…

SAP 财务管理系统 —— 企业财务智能化的领航者

在当今数字化时代&#xff0c;企业财务管理的智能化已成为推动企业持续增长的关键因素。SAP 财务管理系统通过智能化技术&#xff0c;帮助财务部门提高收入、控制成本并降低财务风险&#xff0c;释放财务数字化转型的价值。财务 ERP 作为 SAP 的核心组成部分&#xff0c;将帮助…