数据结构-栈及栈的应用

article/2025/8/16 9:00:39

目录

栈的概述

部分算法分析

顺序栈的表示和实现

global.h

Stack.h

StackTest.cpp

运行结果

栈的应用

数的任意进制转换

括号匹配检验


栈的概述

  •  栈是一种重要的线性结构,属于一种操作受限的线性表
  • 栈(stack) 是限定仅在表尾进行插入或删除操作的线性表
  • 表尾端称为栈顶(top),表头端称为栈底(bottom)
  • 栈的元素遵循先进后出(后进先出),即最先进入栈的元素最后出栈


部分算法分析

  • 栈的初始化
//栈的初始化(构造一个空的栈)
Status InitStack(Stack& S) {//为栈开辟空间S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!S.base)return ERROR;//当top指针与base指针指向地址时,栈为空栈S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
}

 顺序栈,即栈的顺序存储结构,利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,注意:top指针所指的地址并不是存储栈顶数据元素的,而是栈顶数据元素的上一个空间地址

  •  数据入栈操作
//数据元素data入栈操作
Status PushStack(Stack& S, SElemType data) {//判断栈内的数据是否已满,已满追加新的存储空间if (S.top - S.base >= S.stacksize) {//为栈追加新的空间SElemType* newbase;newbase = (SElemType*)realloc(S.base,(S.stacksize + STACK_INCREMENT)*sizeof(SElemType));if (newbase)return ERROR;S.base = newbase;//防止出现新开辟的空间中存储了其它程序的数据被覆盖S.top = S.base + S.stacksize;S.stacksize += STACK_INCREMENT;}if(S.top != NULL)*(S.top++) = data;return OK;
}

追加存储空间使用的是realloc(void *ptr, size_t size) 函数

ptr指针指向一个要重新分配内存的内存块,如果为空指针,则会分配一个新的内存块,且函数返回一个指向它的指针

size内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针

 情况1

 情况2

 在空间扩大的过程中,如果在原地址后有足够的空间追加,则直接在原空间后扩大空间,如果原地址后没有足够的空间追加,则会在新的一块地址区域直接开辟一块size大小的地址空间


 顺序栈的表示和实现

  • global.h
  • Stack.h
  • StackTest.cpp

 global.h

相关头文件的引用,以及相应全局变量、常量的声明

#pragma once#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>using namespace std;#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define EQ(a,b) ((a) == (b))#define LT(a,b) ((a) < (b))#define LQ(a,b) ((a) <= (b))#define MT(a,b) ((a) > (b))#define MQ(a,b) ((a) >= (b))typedef int Status;

Stack.h

顺序栈的定义,以及顺序栈的相关操作算法

#pragma once
#include"global.h"#define STACK_INIT_SIZE 100
#define STACK_INCREMENT 10
#define SElemType int//栈的定义
typedef struct {SElemType* base;  //栈底指针SElemType* top;   //栈顶指针int stacksize;    //栈的空间大小
}Stack;//栈的初始化(构造一个空的栈)
Status InitStack(Stack& S) {//为栈开辟空间S.base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));if (!S.base)return ERROR;//当top指针与base指针指向地址时,栈为空栈S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;
}//空栈的数据赋值操作
Status InitStackData(Stack& S) {//判断该栈是否为空栈if (S.top != S.base) {cout << "该栈不是空栈" << endl;return ERROR;}cout << "输入插入存储数据的个数:" << endl;int nums = 0;cin >> nums;cout << "输入" << nums << "个数据:" << endl;for (int i = 0; i < nums; i++) {cin >> *(S.top++);}return OK;
}//栈的数据遍历
void ShowStack(Stack S) {cout << "栈内的数据元素有:" << endl;while (S.top != S.base) {cout << *(--S.top) << " ";}cout << endl;
}//判断栈是否为空栈
Status StackEmpty(Stack S) {if (S.top == S.base)return OK;return ERROR;
}//栈的销毁
Status DestroyStack(Stack& S) {S.top = S.base;free(S.base);cout << "栈销毁成功" << endl;return OK;
}//将栈置为空栈
Status ClearStack(Stack& S) {S.top = S.base;cout << "栈置为空栈成功" << endl;return OK;
}//输出栈内的数据个数
int StackLength(Stack S) {int length = S.top - S.base;return length;
}//获取栈顶的数据
void GetTop(Stack S) {cout << "栈顶的数据为:" << *(S.top - 1) << endl;
}//数据元素data入栈操作
Status PushStack(Stack& S, SElemType data) {//判断栈内的数据是否已满,已满追加新的存储空间if (S.top - S.base >= S.stacksize) {//为栈追加新的空间SElemType* newbase;newbase = (SElemType*)realloc(S.base,(S.stacksize + STACK_INCREMENT)*sizeof(SElemType));if (newbase)return ERROR;S.base = newbase;//防止出现新开辟的空间中存储了其它程序的数据被覆盖S.top = S.base + S.stacksize;S.stacksize += STACK_INCREMENT;}if(S.top != NULL)*(S.top++) = data;return OK;
}//将栈顶数据元素出栈,并记录出栈的数据元素
Status PopStack(Stack& S, SElemType& data) {//判断栈是否为空,不为空则删除栈顶数据元素(出栈)if (S.top == S.base)return ERROR;data = *(--S.top);return OK;
}

StackTest.cpp

#include"Stack.h"int main() {Stack stack;InitStack(stack);InitStackData(stack);ShowStack(stack);int length = StackLength(stack);cout << "栈内的元素个数为:" << length << endl;SElemType data;GetTop(stack);cout << "入栈操作,请输入入栈的数据:" << endl;cin >> data;PushStack(stack,data);ShowStack(stack);cout << "------出栈操作------" << endl;PopStack(stack, data);cout << "出栈的数据是:" << data << endl;ShowStack(stack);
}

运行结果

输入插入存储数据的个数:
5
输入5个数据:
12 23 43 21 56
栈内的数据元素有:
56 21 43 23 12
栈内的元素个数为:5
栈顶的数据为:56
入栈操作,请输入入栈的数据:
87
栈内的数据元素有:
87 56 21 43 23 12
------出栈操作------
出栈的数据是:87
栈内的数据元素有:
56 21 43 23 12

F:\DataStructureForC++\Project\Debug\Project1.exe (process 5248) exited with code 0.


 栈的应用

  • 数的任意进制转换
  • 括号匹配检验
  • 表达式求值

 数的任意进制转换

将一个十进制数N与其他d进制数转换,基于下列原理

N = (N div d) × d + N mod d (div为整除运算,mod为求余运算)

/*
* 数的任意进制转换
* 用户输入任意非负正整数,再输入一个进制数
*/
void NumberConversion(int number,int baseNumber) {//判断输入的数是否为正整数if (number < 0) {cout << "输入的数不能为负数" << endl;exit(0);}Stack stack;SElemType data;InitStack(stack);cout << number << "转化" << baseNumber << "进制后的数为:" << endl;while (number) {PushStack(stack, number % baseNumber);number = number / baseNumber;}while (!StackEmpty(stack)) {PopStack(stack, data);cout << data;}cout << endl;
}

 运行结果

 请输入一个非负的十进制整数
8
请输入一个进制数:
2
8转化2进制后的数为:
1000


请输入一个非负的十进制整数
89
请输入一个进制数:
8
89转化8进制后的数为:
131

括号匹配检验

假设表达式中允许包含两种括号:圆括号()和方括号 [ ] ,其嵌套顺序随意,检验括号嵌套的格式是否正确

/*
* 括号匹配检验
* 用户输入方括号和圆括号,检验括号是否匹配
* charArray数组以'#'作为最后一个数据元素(循环终止条件)
*/
void BracketMatch(char charArray[]) {Stack stack;InitStack(stack);SElemType c;while (*charArray != '#') {switch ((*charArray)) {case ')':PopStack(stack, c);if (c != '(') {cout << ") 括号不匹配" << endl;exit(0);}break;case ']':PopStack(stack, c);if (c != '[') {cout << "] 括号不匹配" << endl;exit(0);}break;default://如果不是右括号,将该括号进栈PushStack(stack, *(charArray));}charArray++;}cout << "括号匹配成功" << endl;
}

 运行结果

输入的括号为:
( [ ] ) 括号匹配成功


输入的括号为:
( [ ( ] ] ) ] 括号不匹配

F:\DataStructureForC++\Project\Debug\Project1.exe (process 2124) exited with code 0.

注意:将Stack.h头文件中的#define SElemType int改为char

 括号匹配函数中,如果遇到左括号则入栈,遇到右括号则进入switch( )语句,将栈内的栈顶元素出栈(该元素为最内层的括号),检查括号是否匹配


http://chatgpt.dhexx.cn/article/bfLYmg0b.shtml

相关文章

java数据结构-栈

栈 1、栈的定义 栈&#xff08;Stack&#xff09;&#xff1a;是只允许在一端进行插入或删除的线性表。首先栈是一种线性表&#xff0c;但限定这种线性表只能在某一端进行插入和删除操作。 栈顶&#xff08;Top&#xff09;&#xff1a;线性表允许进行插入删除的那一端。 栈底…

数据结构栈(顺序栈、链栈、插入push、删除pop)、队(循环队,链队、入队push,出队pop)知识点梳理

数据结构栈知识点梳理 一 栈的定义 栈&#xff08;stack&#xff09;是限定仅在表尾进行插入和删除操作的线性表 不含任何元素的栈称为空栈 允许插入和删除的一端成为栈顶&#xff08;top&#xff09;&#xff0c;另一端称为栈底&#xff08;bottom&#xff09; 具有LIFO&a…

数据结构栈和队列

整本书的知识点&#xff0c;点击右方链接&#xff1a;整本书笔记知识点 文章目录 三、栈和队列3.1、栈和队列的定义和特点3.1.1、栈的定义和特点3.1.2、队列的定义和特点 3.2、案例引入3.3、栈的表示和操作的实现3.3.1、栈的类型定义3.3.2、顺序栈的表示和实现3.3.3、链栈的表示…

C++数据结构——栈

C数据结构——栈 最近计划再复习一遍数据结构&#xff0c;看到一篇博客&#xff1a;https://www.cnblogs.com/QG-whz/p/5170418.html#_label0。 1、栈(Stack)是一种线性存储结构&#xff0c;它具有如下特点&#xff1a; &#xff08;1&#xff09;栈中的数据元素遵守“先进后…

数据结构 栈-链栈及基本操作

目录 一.栈的定义二.栈的特点三.栈的理解四.链栈引入五.链栈定义六.链栈的结构体设计七.链栈的基本操作7.1链栈的初始化7.2链栈判空7.3链栈入栈7.4链栈出栈7.4取栈顶元素 八.总结 一.栈的定义 栈是限定仅在表尾进行插入和删除操作的数据结构&#xff08;受到限制的线性表&…

数据结构之——栈

文章目录 数据结构之——栈一&#xff1a;栈的定义&#xff1a;二&#xff1a;栈的抽象数据类型&#xff1a;三&#xff1a;栈的顺序存储结构及其实现&#xff1a;1: 预说明&#xff1a;2&#xff1a;栈的顺序存储结构——结构定义&#xff1a;3:栈的顺序存储结构——进栈操作4…

数据结构与算法(3)栈

栈 1、栈的一个实际需求 请输入一个表达式&#xff1a;7x2x2-51-53-3 2、栈的介绍 栈的英文为stack 栈是一个**先入后出(FILO-First In Last Out) **的有序列表 栈(stack) 是限制线性表中元素的插入和删除只能在线性表的同一端进行的一种特殊线性表。 允许插入和删除的一端…

【数据结构】栈

栈的概念及结构 在学习栈前&#xff0c;我们先看一下栈的正式解释&#xff1a; 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。 栈中的数据元素遵守后进先出 L…

什么是栈?

本文将介绍一个重要的数据结构—栈&#xff0c;和之前讲到的链表、数组一样也是一种数据呈线性排列的数据结构&#xff0c;不过在这种结构中&#xff0c;我们只能访问最新添加的数据。栈就像是一摞书&#xff0c;拿到新书时我们会把它放在书堆的最上面&#xff0c;取书时也只能…

【图解数据结构】栈全面总结

目录 一、前言 二、基本概念 三、栈的表示和实现 1.顺序栈 2.链栈 四、栈的常见算法实现 1.初始化 2.判空 3.判满 4.顺序栈取栈顶元素 5.顺序栈入栈 6.顺序栈出栈 五、双栈 1.双端顺序栈进栈操作 2.双端顺序栈出栈操作 六、栈的应用举例 1.回文游戏 2.多进制…

数据结构——栈

栈和队列 栈和队列介绍特点栈、队列与一般线性表的区别栈——stack栈的基本运算栈的存储结构顺序栈链栈 栈的应用 栈和队列 介绍 栈和队列是在软件设计中常用的两种数据结构&#xff0c;它们的逻辑结构和线性表相同 特点 栈和队列在运算上受到了限制&#xff1a;栈是按照“…

遥感影像百分比线性拉伸

AI Earth地球科学云平台开发者模式提供了丰富的遥感数据和函数计算能力&#xff0c;下面介绍结合AIE Notebook&#xff0c;实现遥感数据的百分比线性灰度拉伸。 本期开发者实践案例——遥感影像百分比线性拉伸 灰度拉伸 (GrayScale Stretch) 是遥感影像处理过程中的重要步骤&…

遥感影像分类方法

最初的遥感影像分类是通过目视解译(濮静娟, 1984)来完成的&#xff0c;对研究人员的主观意识有较强的依赖性&#xff0c;而且效率较低&#xff0c;适用于数据量较小的情况&#xff0c;通常作为其他方法对比的对象。目前的遥感图像分类主要以计算机分类为主&#xff0c;因此按照…

遥感影像配准

文章目录 前言步骤1.ENVI&#xff1a;打开Image Registration Workflow2.Image Registration Workflow(1)选择GF2为Base Image File&#xff0c;某季节Sentinel2为Warp&#xff0c;然后Next(2)修改该参数为100(3)人为选择5个左右控制点&#xff0c;然后Next(4)删除离谱点(5)在E…

遥感图像分类技术

什么是遥感图像分类技术&#xff1f; 图像分类是将土地覆盖类别分配给像素的过程。例如&#xff0c;这9个全球土地覆盖数据集将图像分为森林、城市、农业和其他类别。 https://gisgeography.com/free-global-land-cover-land-use-data/ 一般来说&#xff0c;这是遥感中的三种主…

遥感图像分类

遥感图像分类 一、背景简介 遥感图像分类就是利用计算机通过对遥感图像中各类地物的光谱信息和空间信息进行分析&#xff0c;选择特征&#xff0c;将图像中各个像元按照某种规则或算法划分不同的类别&#xff0c;然后获得遥感图像中与实际地物的对应信息&#xff0c;从而实现…

WorldView卫星遥感影像数据/米级分辨率遥感影像

数据样例&#xff1a;百度云下载链接&#xff1a;https://pan.baidu.com/s/17ofPwpDM3OCHnE-LuhvUp 提取码&#xff1a;i0m4 目前世界上最常用的高分辨率卫星影像莫过于WORLDVIEW系列了&#xff0c;在卫星遥感圈内可谓大名鼎鼎&#xff0c;不仅具有超高的分辨率还具有其他高分…

遥感数据下载平台汇总

1中国资源卫星应用中心http://www.cresda.com.cn中巴卫星、HJ星、ZY系列 、GF系列2中科院对地观测与数字地球科学中心http://ids.ceode.ac.cn/Index.aspxERS卫星&#xff0c;Enviset_1卫星&#xff0c;法国的spot4卫星&#xff0c;中巴资源卫星&#xff0c;landset-5-73地球系统…

遥感多光谱数据下载与预处理(一、数据选择 下载)

首先说明本人并非专业大牛&#xff0c;不是教程贴只是记录一下学习过程和大家交流&#xff0c;过程有不严谨不合规范不对的地方欢迎各位大神指正。 本人目前做过接触过最多的是多光谱遥感数据&#xff0c;也是与无人机、雷达、高光谱等相比最简单的一种&#xff0c;这是我自己总…

地理空间数据云下载遥感影像

目录 1、先上网址&#xff1a;www.gscloud.cn 2、介绍界面&#xff1a; 2.1 “数据资源” 2.2 “高级检索” 1、先上网址&#xff1a;www.gscloud.cn 2、介绍界面&#xff1a; 地理空间数据云&#xff0c;作为国内免费下载遥感卫星影像的一个大平台&#xff0c;随着年代发…