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

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.hqwc.cn/news/671490.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

multipass和multipassd命令的区别

multipassd通常是multipass服务的后台守护进程&#xff0c;它负责管理和控制虚拟机实例。 命令区别 例&#xff1a; multipass restart my-vm 这个命令用于重启Multipass中的虚拟机实例。例如有一个名为my-vm的虚拟机实例。 multipassd restart 这会重新启动Multipass后台…

达梦主从数据库实例恢复

测试环境&#xff1a;实时主备数据库 1、在节点1向测试表aaa插入数据 如图可见&#xff0c;会话139695153554808向aaa表插入了10000行数据。事务id460520。 2、提交前在另一个窗口kill掉dmserver进程。 3、查看节点2的数据库日志 上图可见&#xff0c;系统执行alter database…

Android虚拟机机制

目录 一、Android 虚拟机 dalvik/art&#xff08;6版本后&#xff09;二、Android dex、odex、oat、vdex、art区别 一、Android 虚拟机 dalvik/art&#xff08;6版本后&#xff09; 每个应用都在其自己的进程中运行&#xff0c;都有自己的虚拟机实例。ART通过执行DEX文件可在设…

4.任务创建和删除的API函数

一、简介 二、动态创建任务函数:xTaskCreate() 此函数用于使用动态的方式创建任务&#xff0c;任务的任务控制块以及任务的栈空间所需的内存&#xff0c;均由 FreeRTOS 从 FreeRTOS 管理的堆中分配&#xff0c;若使用此函数&#xff0c;需要在 FreeRTOSConfig.h 文件 中将宏 c…

原型图制作神器!6款软件推荐,助你轻松实现设计构想!

在现代设计领域&#xff0c;原型图的制作是一个至关重要的环节。它们帮助设计师将创意转化为可视化界面&#xff0c;评估用户体验并进行交互测试。本文将介绍六款备受推崇的原型图软件&#xff0c;它们以强大的功能、易用的界面和灵活的工作流程脱颖而出&#xff0c;为设计师创…

灌溉机器人 状压dp

灌溉机器人 题目描述 农田灌溉是一项十分费体力的农活&#xff0c;特别是大型的农田。小明想为农民伯伯们减轻农作负担&#xff0c;最近在研究一款高科技——灌溉机器人。它可以在远程电脑控制下&#xff0c;给农田里的作物进行灌溉。 现在有一片 N 行 M 列的农田。农田的土…

Python_4-对象序列化操作

文章目录 Python中对象数据持久化操作模块学习笔记marshal模块优点缺点使用示例保存数据到文件从文件读取数据 shelve模块优点缺点使用示例保存数据到文件从文件读取数据 总结 Python中对象数据持久化操作模块学习笔记 在Python中&#xff0c;数据持久化指的是将程序中的数据结…

Unity 性能优化之遮挡剔除(Occlusion Culling)(六)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、遮挡剔除是什么&#xff1f;二、静态遮挡剔除的使用步骤1.标记为遮挡剔除对象2.创建Occlusion Area组件3.烘焙4.Occlusion窗口Bake的参数Smallest Oc…

快速入门!学习鸿蒙App开发的终极指南!

鸿蒙&#xff08;HarmonyOS&#xff09;是华为推出的一款分布式操作系统&#xff0c;旨在为不同设备提供统一的操作体验。鸿蒙App开发可以让应用程序在多个设备上实现流畅运行。本文将介绍鸿蒙App开发的终极指南&#xff0c;帮助您快速入门。 开发环境搭建 鸿蒙App开发过程需要…

Linux PXE高效批量网络装机

系统初始化 systemctl disable --now firewalld.service setenforce 0 vim /etc/selinux/config 安装软件 yum install -y tftp-server xinetd dhcp vsftpd syslinux 复制 vmlinuz initrd.img pxelinux.0 到 /var/lib/tftpboot/ 目录 [rootlocalhost ~]# cd /mnt/…

遥遥领先们赚钱的路子,被香飘飘找到了……?

刚刚结束了的五一长假&#xff0c;中文互联网上可以说满是各种对立、冲突。 让人惋惜的胖猫及遭万人唾弃的捞女谭竹之外&#xff0c;曾经卖奶茶杯子绕地球几圈&#xff0c;如今却被多数人遗忘的香飘飘&#xff0c;一通操作下来&#xff0c;让不少吃瓜群众小刀剌屁股开了眼了……

nacos开启登录开关启动报错“Unable to start embedded Tomcat”

nacos 版本&#xff1a;2.3.2 2.2.2版本之前的Nacos默认控制台&#xff0c;无论服务端是否开启鉴权&#xff0c;都会存在一个登录页&#xff1b;在之后的版本关闭了默认登录页面&#xff0c;无需登录直接进入控制台操作。在这里我们可以在官网可以看到相关介绍 而我现在所用的…