【数据结构】C++语言实现栈(详细解读)

news2024/11/24 9:28:52

9efbcbc3d25747719da38c01b3fa9b4f.gif

 c语言中的小小白-CSDN博客c语言中的小小白关注算法,c++,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm=1001.2014.3001.5343

给大家分享一句我很喜欢我话:

知不足而奋进,望远山而前行!!!

铁铁们,成功的路上必然是孤独且艰难的,但是我们不可以放弃,远山就在前方,但我们能力仍然不足,所有我们更要奋进前行!!!

今天我们更新了内容,

🎉 欢迎大家关注🔍点赞👍收藏⭐️留言📝

什么是

栈的概念及结构

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为 栈顶 ,另一端称为 栈底 。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在 栈顶。
出栈:栈的删除操作叫做出栈。 出数据也在 栈顶。
栈的结构:

实现栈的方式:

实现栈的方式有两种: 顺序表链表

链表的优缺点:

优点:

        1、任意位置插入删除O(1)

        2、按需申请释放空间

缺点:

        1、不支持下标随机访问

        2、CPU高速缓存命中率会更低

顺序表的优缺点:

优点:1、尾插尾删效率不错。

        2、下标的随机访问。

        3、CPU高速缓存命中率会更高

缺点:

        1、前面部分插入删除数据,效率是O(N),需要挪动数据。

        2、空间不够,需要扩容。a、扩容是需要付出代价的 b、一般还会伴随空间浪费。

综上所述,用顺序表实现栈更好。

栈的实现

a.头文件的包含

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

 b.栈的定义

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶
	int capacity;//栈的容量
}ST;

c.接口函数  

// 初始化栈
void STInit(ST* pst); 
 
// 入栈
void STPush(ST* pst, STDataType data); 
 
// 出栈
void STPop(ST* pst); 
 
// 获取栈顶元素
STDataType STTop(ST* pst); 
 
// 获取栈中有效元素个数
int STSize(ST* pst); 
 
// 检测栈是否为空,如果为空返回true,如果不为空返回false
bool STEmpty(ST* pst); 
 
// 销毁栈
void STDestroy(ST* pst);

接口函数的实现

1.栈的初始化

pst->top表示栈的顶部指针,通常情况下,它指向栈顶元素的下一个位置,而不是指向当前栈顶元素。通过 pst->top 可以确定栈中元素的个数,打印的时候记得将 top - 1。

void STInit(ST* pst)
{
	assert(pst);//防止敲代码的人传过来是NULL指针
	
    pst->a = NULL;//栈底
	
    //top不是数组下标,不能理解成数组下标,因为栈只能拿到栈顶的元素,而数组可以随机访问拿到中间元素
    //pst->top=-1;//指向栈顶元素
	
    pst->top = 0;//指向栈顶元素的下一个位置
	pst->capacity = 0;
 
}

2.销毁栈

void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
}

3.入栈

这里我们会运用到三目运算符

 
void STPush(ST* pst,STDataType x)
{
	if (pst->top == pst->capacity)
	{
		int 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;//返回的是realloc出来的内存块的地址
		pst->capacity = newCapacity;//把扩容后的空间大小赋值给栈容量
	}
	pst->a[pst->top] = x;//先放值
	pst->top++;//再++
}

4.检测栈是否为空

bool STEmpty(ST* pst)//栈为空返回true,不为空返回false
{
    //写法一
	//assert(pst);
	//if (pst->top == 0)
	//{
	//	return true;
	//}
	//else
	//{
	//	return false;
	//}
	
    //写法二
    return pst->top == 0;
}

  • 当栈为空时,表示栈中没有任何元素。此时,栈顶指针 top 的值通常被设置为特定的初始值(例如0或-1),指向栈底或栈外。在这种情况下,栈顶指针没有指向有效的元素,因此栈被认为是空的。
  • 当栈非空时,表示栈中至少有一个元素。此时,栈顶指针top的值指向栈顶元素的位置。栈顶元素是最后一个被入栈的元素,也是最先被访问或移除的元素。只要栈中有元素存在,栈顶指针都会指向有效的位置。

5.出栈

void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}

6.获取栈顶元素

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
 
	return pst->a[pst->top - 1];
}

7.获取栈中有效元素个数

int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}

完整代码:

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void TestStack1()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	while (!STEmpty(&st))
	{
		printf("%d ", STTop(&st));//栈顶元素
		STPop(&st);
	}
	STDestroy(&st);
}
void TestStack2()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	printf("%d ", STTop(&st));
	STPush(&st, 3);
	STPush(&st, 4);
	printf("\n");
	printf("%d ", STTop(&st));
	//printf("%d", STSize(&st));
	//while (!STEmpty(&st))
	//{
	//	printf("%d ", STTop(&st));//栈顶元素
	//	STPop(&st);
	//}
	STDestroy(&st);
}
void TestStack3()
{
	ST st;
	STInit(&st);
	STPush(&st, 1);
	STPush(&st, 2);
	STPush(&st, 3);
	STPush(&st, 4);
	//printf("%d", STSize(&st));
 
	STDestroy(&st);
}
 
int main()
{
	TestStack1();//入栈出栈
	//TestStack2();//获取栈顶元素
	//TestStack3();//计算栈中有效元素个数 
	return 0;
}

Stack.h

#pragma once
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<stdio.h>
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶的位置
	int capacity;//栈的容量
}ST;
 
void STInit(ST* pst);
void STDestroy(ST* pst);
void STPush(ST* pst,STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);
bool  STEmpty(ST* pst);
int STSize(ST*pst);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void STInit(ST* pst)
{
	assert(pst);
	pst->a = NULL;//栈底
	
	//top不是下标
    //pst->top=-1;//指向栈顶元素
	pst->top = 0;//指向栈顶元素的下一个位置
	pst->capacity = 0;
 
}
 
void STDestroy(ST* pst)
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
}
 
 
void STPush(ST* pst,STDataType x)
{
	if (pst->top == pst->capacity)
	{
		int newCapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;//true,4.false,括2倍
 
		STDataType* tmp = (STDataType*)realloc(pst->a, newCapacity * sizeof(STDataType));//返回值地址相等就是原地扩容,不同就是异地扩
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->a = tmp;//返回的是realloc出来的内存块的地址
		pst->capacity = newCapacity;//把扩容后的空间大小赋值给栈容量
	}
	pst->a[pst->top] = x;//先放值
	pst->top++;//再++
}
 
 
void STPop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
	pst->top--;
}
 
 
STDataType STTop(ST* pst)
{
	assert(pst);
	assert(!STEmpty(pst));
 
	return pst->a[pst->top - 1];
}
 
bool STEmpty(ST* pst)//栈为空返回true,不为空返回false
{
	//assert(pst);
	//if (pst->top == 0)
	//{
	//	return true;
	//}
	//else
	//{
	//	return false;
	//}
	return pst->top == 0;
}
int STSize(ST* pst)
{
	assert(pst);
	return pst->top;
}
 

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

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

相关文章

cmake进阶:文件操作

一. 简介 前面几篇文章学习了 cmake的文件操作&#xff0c;写文件&#xff0c;读文件。文章如下&#xff1a; cmake进阶&#xff1a;文件操作之写文件-CSDN博客 cmake进阶&#xff1a;文件操作之读文件-CSDN博客 本文继续学习文件操作。主要学习 文件重命名&#xff0c;删…

自动化运维管理工具-------------Ansible

目录 一、自动化运维工具有哪些&#xff1f; 1.1Chef 1.2puppet 1.3Saltstack 二、Ansible介绍 2.1Ansible简介 2.2Ansible特点 2.3Ansible工作原理及流程 2.3.1内部流程 2.3.2外部流程 三、Ansible部署 3.1环境准备 3.2管理端安装 ansible 3.3Ansible相关文件 …

BGP的选路 :

前提条件 &#xff1a; 丢弃所有不可用的路由信息。 属性的名称 传播范围 默认值 评判标准 PV&#xff08;优选值&#xff09; 不传播 0&#xff08;0-65535&#xff09; 越大越优 LP&#xff08;本地优先级&#xff09; IBGP对等体 之间 100 越大越优 AS_PATH …

0506_IO1

思维导图&#xff1a; 练习&#xff1a; 有如下结构体 struct Student{ char name[16]; int age; double math_score; double chinese_score; double english_score; double physics_score; double chemistry_score; double bio_score; }; 申请该结构体数组&#xff0c;容量为…

尊享面试100题(314.二叉树的垂直遍历python)

题目关键词&#xff0c;从左到右&#xff0c;从上到下&#xff0c;那么使用bfs宽度优先算法。 使用字典v保存每一列的值。 class Solution:def verticalOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if not root: return []v defaultdict(list)qu deque()…

数据分析之Tebleau可视化:树状图、日历图、气泡图

树状图&#xff08;适合子分类比较多的&#xff09; 1.基本树状图的绘制 同时选择产品子分类和销售金额----选择智能推荐----选择树状图 2.双层树状图的绘制 将第二个维度地区拖到产品分类的下面---大的划分区域是上面的维度&#xff08;产品分类&#xff09;&#xff0c;看着…

GreptimeDB 助力国家电网数字换流站打造稳定高效的时序数据底座

电网体系作为现代社会运行的支柱之一&#xff0c;为各行各业、千家万户提供了电能的基本支持。从家庭到企业&#xff0c;医院到学校&#xff0c;交通到通讯&#xff0c;电力电网的应用贯穿始终。近年来&#xff0c;特高压换流站成为国家电网的重点建设工程&#xff0c;“十四五…

[每日AI·0506]巴菲特谈 AI,李飞飞创业,苹果或将推出 AI 功能,ChatGPT 版搜索引擎

AI 资讯 苹果或将推出 AI 功能&#xff0c;随 iPhone 发布2024 年巴菲特股东大会&#xff0c;巴菲特将 AI 类比为核技术 巴菲特股东大会 5 万字实录消息称 OpenAI 将于 5 月 9 日发布 ChatGPT 版搜索引擎路透社消息&#xff0c;斯坦福大学 AI 领军人物李飞飞打造“空间智能”创…

Linux第三节--常见的指令介绍集合(持续更新中)

点赞关注不迷路&#xff01;&#xff0c;本节涉及初识Linux第三节&#xff0c;主要为常见的几条指令介绍。 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1f44d;&#x1f3fb; 收藏 ✨ 加关注&#x1f440; 期待与你共同进步! Linux下基本指令 1. man指令 Linu…

学QT的第一天~

#include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { //窗口相关设置// this->resize(427,330); this->setFixedSize(427,330); //设置图标 this->setWindowIcon(QIcon("C:\\Users\\Admin\\Desktop\\pictrue\\dahz.jpg&q…

ComfyUI搭建和注意事项for WIN[笔记]

下载ComfyUI(GitHub - comfyanonymous/ComfyUI: The most powerful and modular stable diffusion GUI, api and backend with a graph/nodes interface.) 从源码上搭建比较麻烦&#xff0c;一般不推荐&#xff0c;所以跑到release里面找一个下载。我的显卡是GeFore GTX 1050 …

mac电脑如何安装python及环境搭建

&#xff08;1&#xff09;进入官网&#xff1a;Download Python | Python.org&#xff0c;根据自己电脑选择python (2)这里我选择的是mac,点击&#xff1a;macos&#xff0c;选择最近版本并点击进入 (3)选择mac版本&#xff1a; (4)点击就可以进入下载&#xff1a; (5)下载好之…

全国31省对外开放程度、经济发展水平、ZF干预程度指标数据(2000-2022年)

01、数据介绍 自2000年至2022年&#xff0c;中国的对外开放程度不断深化、经济发展水平不断提高、ZF不断探索并调整自身在经济运行中的角色和定位&#xff0c;以更好地适应国内外环境的变化&#xff0c;也取得了举世瞩目的成就。这一期间&#xff0c;中国积极融入全球经济体系…

JAVA基础|常用API-BigDecimal

一. 说明 用于解决浮点型运算时&#xff0c;出现结果失真的问题。 由于计算机本身的二进制并不能很精确的计算度&#xff0c;直接进行 - * /也可能出现运算结果失真 可以看到在上述代码中&#xff0c;0.10.2并不完全等于0.3&#xff0c;这在某些情况下会出现问题&#xff0c;…

Day61:单调栈 739. 每日温度 496.下一个更大元素 I

739. 每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置用 0 来代替。 示例 1: 输…

Vue 介绍

【1】前端发展史 前端的发展史可简述为&#xff1a; 从最初的静态页面编写&#xff0c;依赖后端模板渲染逐步演化为通过JavaScript&#xff08;特别是Ajax技术&#xff09;实现前后端分离&#xff0c;使得前端能够独立地加载数据和渲染页面随后&#xff0c;Angular、React、Vu…

堡垒机——网络技术手段

目录 一、简介 1.什么是跳板机 2.跳板机缺陷 3.什么是堡垒机 4.为什么要使用堡垒机 4.1堡垒机设计理念 4.2堡垒机的建设目标 4.3堡垒机的价值 4.4总结 5.堡垒机的分类 6.堡垒机的原理 7.堡垒机的身份认证 8.堡垒机的运维方式常见有以下几种 9.堡垒机其他常见功能…

docker安装redis命令及运行

docker安装redis&#xff1a; docker run -d -p 6379:6379 --name redis redis:latest -d: 以 守护进程模式 运行容器&#xff0c;容器启动后会进入后台运行&#xff0c;并脱离当前命令行会话。 -p: 显示端口号。 -p 6379:6379: 将容器内部的 6379 端口映射到宿主机 6379 端…

OpenHarmony实战开发-上传文件

Web组件支持前端页面选择文件上传功能&#xff0c;应用开发者可以使用onShowFileSelector()接口来处理前端页面文件上传的请求。 下面的示例中&#xff0c;当用户在前端页面点击文件上传按钮&#xff0c;应用侧在onShowFileSelector()接口中收到文件上传请求&#xff0c;在此接…

行业唯一!易保全牵头编制的《区块链数据访问安全技术通则》发布

近日&#xff0c;易保全牵头参与编制的《区块链数据访问安全技术通则》经中国国际经济技术合作促进会正式发布&#xff0c;为中国区块链数据安全技术提供了标准参考。 易保全作为牵头起草单位、易保全CEO兼董事长刘刚担任主要起草人参与其中&#xff0c;在区块链技术安全风险…