数据结构:栈 及其应用

ops/2024/10/19 4:19:04/

逻辑结构:

栈(Stack)是一种遵循后进先出(LIFO, Last In First Out)原则的有序集合 (受限的线性表)。这种数据结构只允许在栈顶进行添加(push)或删除(pop)元素的操作。栈是一种非常基础且重要的数据结构,广泛应用于计算机科学和软件开发中。

栈顶:插入和删除

栈底:固定的 不允许插入和删除

空栈:不含任何元素

栈的基本操作

  1. push(element): 向栈顶添加一个元素。如果栈已满,则可能无法进行此操作。
  2. pop(): 移除栈顶的元素,并返回该元素。如果栈为空,则可能无法进行此操作,并可能返回一个错误或特殊值(如nullundefined)。
  3. peek() 或 top(): 返回栈顶元素的值,但不从栈中移除它。如果栈为空,则可能返回一个错误或特殊值。
  4. isEmpty(): 检查栈是否为空。
  5. size(): 返回栈中元素的数量。

栈的存储结构:

栈可以通过多种方式实现,包括使用数组(或列表)和链表。

顺序存储:
  • 基于数组的栈(顺序栈):在这种实现中,数组的一端被用作栈顶。添加元素时,新元素被添加到数组的末尾;移除元素时,数组的最后一个元素被移除。这种实现方式在大多数编程语言中都非常高效,因为数组的末尾操作通常很快。

初始化:

# define MaxSize 50
typedef struct
{Elemtype data[MaxSize];int top;//栈顶指针}SqStack;//iniiallize
void initStack(SqStack &s){ 
s.top=-1;
}

判断非空:

//empty
bool StackEmpty(SqStack s){if(s.top==-1)return true;elsereturn false;
}

 进栈:

//in
bool Push(SqStack &s,Elemtype e){if(s.top==MaxSize-1)return false;else{s.top++;s.data[s.top]=e;}return true;}

进栈和出栈的操作 根据s.top的初始值不同而不同:
s.top=-1先指针+1再进栈,先出栈再指针-1;

s.top=0先进栈再指针+1,先指针-1再出栈; 

 出栈:

bool Pop(SqStack &s,Elemtype &e){if(s.top==-1)return false;e=s.data[s.top];s.top--;return true;
}

读取栈顶元素:

//read
bool GetTop(SqStack s,Elemtype &x){if(s.top==-1)return false;x=s.data[s.top];
return true;
}
 链式存储:
  • 基于链表的栈:下列代码规定没有头结点,LHead指向栈顶元素,链表的头部被用作栈顶。添加元素时,新元素被添加到链表的头部;移除元素时,链表的第一个元素(即头部元素)被移除。虽然链表在随机访问方面不如数组高效,但在某些情况下(如动态内存分配),链表可能更灵活。

//
typedef struct LinkNode
{Elemtype data;struct LinkNode *next;}LiStack;

栈的应用

栈的应用非常广泛,包括但不限于:

  • 函数调用

在大多数编程语言中,函数调用是通过栈来实现的。当函数被调用时,其返回地址和局部变量被推入栈中;当函数返回时,这些信息从栈中弹出。

  • 表达式求值

在编译器和解释器中,栈用于计算表达式的值。例如,在解析算术表达式时,可以使用栈来跟踪操作符和操作数。

中缀转后缀:

1)加括号:(( A +③( B *②( C -① D )))-©( E /④ F ))。

2)运算符后移:(( A ( B ( CD )-①)*②)+③( EF )/④)-⑤。

3)去除括号后,得到后缀表达式: ABCD -①*②+③ EF /④-⑤.

在计算机中,中缀表达式转后缀表达式时需要借助一个栈,用于保存暂时还不能确定运算顺序的运算符。从左到右依次扫描中缀表达式中的每一项,具体转化过程如下:
1)遇到操作数。直接加入后缀表达式。
2)遇到界限符。若为"(",则直接入栈;若为")",则依次弹出栈中的运算符,并加入后缀表达式,直到弹出"("为止。注意,"("直接删除,不加入后缀表达式。

3)遇到运算符。若其优先级高于除"("外的栈顶运算符,则直接入栈。否则,从栈顶开始,依次弹出栈中优先级高于或等于当前运算符的所有运算符,并加入后缀表达式,直到遇到一个优先级低于它的运算符或遇到"("时为止,之后将当前运算符入栈。按上述方法扫描所有字符后,将栈中剩余运算符依次弹出,并加入后缀表达式。

转后缀图解(例子):

后缀表达式求值:

通过后缀表示计算表达式值的过程:从左往右依次扫描表达式的每一项,若该项是操作数,则将其压入栈中;若该项是操作符< op >,则从栈中退出两个操作数 Y 和 x ,形成运算指令 X < op > y ,并将计算结果压入栈中。当所有项都扫描并处理完后,栈顶存放的就是最后的计算结果。

后缀求值图解:

  • 括号匹配

栈可以用来检查括号(如圆括号、方括号和花括号)是否正确匹配。

  • 回溯算法

在解决某些问题时(如迷宫问题、八皇后问题等),栈可以用来保存中间状态,以便在需要时回溯到之前的状态。

  • 页面访问历史

在Web浏览器中,栈可以用来保存用户访问的页面历史,以便用户可以通过“后退”按钮返回到之前的页面。

总之,栈是一种简单但功能强大的数据结构,其独特的后进先出原则使得它在许多应用场景中都非常有用。


http://www.ppmy.cn/ops/118077.html

相关文章

.NET IIS发布项目后设置虚拟路径访问文件 404

解决方案: 找到Startup.cs中适当配置静态文件中间件&#xff1a; 确保调用了UseStaticFiles中间件 public void Configure(IApplicationBuilder app) {app.UseStaticFiles(); // 确保这行在UseRouting之前app.UseRouting();app.UseAuthorization();app.UseEndpoints(endpoin…

Ubuntu/Debian网络配置(补充篇)

Ubuntu/Debian网络配置补充 在《Ubuntu/Debian网络配置 & Ubuntu禁用自动更新_ubuntu nmtui-CSDN博客》上总结的“配置网络”章节&#xff0c;对于新版本或者“最小化安装”场景&#xff0c;可能不适应&#xff0c;故此本文做一下补充&#xff0c;就不在原有文章上做更新了…

不同领域的常见 OOD(Out-of-Distribution)数据集例子

以下是几个来自不同领域的常见 OOD&#xff08;Out-of-Distribution&#xff09;数据集例子&#xff0c;这些数据集常用于测试和研究模型在分布变化或分布外数据上的泛化能力&#xff1a; 1. 计算机视觉领域 CIFAR-10 vs. CIFAR-10-C / CIFAR-100-C: 描述&#xff1a;CIFAR-10…

Java:插入排序

目录 排序的概念 插入排序 直接插入排序 哈希排序 排序的概念 排序&#xff1a;所谓的排序&#xff0c;就是使一串记录&#xff0c;按照某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个…

Lagent 自定义你的 Agent 智能体

任务&#xff1a;使用 Lagent 自定义一个智能体&#xff0c;并使用 Lagent Web Demo 成功部署与调用 复现过程 1、根据教材部署环境。https://github.com/InternLM/Tutorial/blob/camp3/docs/L2/Lagent/readme.md 2、启动Lagent Web Demo 和LMDeploy api_server&#xff0c;…

c++模拟真人鼠标轨迹算法

一.鼠标轨迹算法简介 鼠标轨迹底层实现采用 C / C语言&#xff0c;利用其高性能和系统级访问能力&#xff0c;开发出高效的鼠标轨迹模拟算法。通过将算法封装为 DLL&#xff08;动态链接库&#xff09;&#xff0c;可以方便地在不同的编程环境中调用&#xff0c;实现跨语言的兼…

Splashtop 在2024年 CybersecAsia 读者之选奖项评选中荣获新星奖

2024年9月26日 新加坡 安全远程访问和支持解决方案领域的领先企业 Splashtop 在第五届 CybersecAsia 读者之选奖项评选中荣获新星奖。该奖项的评选人员包括首席信息安全官、技术领袖和网络安全从业者&#xff0c;旨在表彰亚太地区网络安全领袖在行业中发挥的关键作用、取得的创…

OpenHarmony(鸿蒙南向)——平台驱动开发【PIN】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 概述 功能简介 PIN即管脚控制器&#xff0c;用于统一管理各SoC的…