数据结构定义和特点--栈

什么是栈

  1. 后进先出,先进后出,这就是典型的栈结构。
  2. 从栈的操作特性来看,是一种操作受限的线性表,只允许在端插入和删除数据。

为什么需要栈

  1. 任何数据结构都是对特定应用场景的抽象,数组和链表虽然使用起来更加灵活,但是暴露了几乎所有的操作,难免会引发错误。
  2. 当某个数据集合只涉及在某端插入和删除数据,且满足后进者先出、先进者后出的操作特性时,我们应该首选栈这种数据结构。

如何实现栈

  1. 栈的API
public class Stack<item>{
    // 压栈
    public void push(Item item){}
    // 弹栈
    public Item pop(){}
    // 是否为空
    public boolean isEmpty(){}
    // 栈中数据量
    public int size(){}
    // 查看最近添加的数据,却不删除它
    public Item peek(){}
}
  1. 数组实现(自动扩容)
  • 时间复杂度:根据均摊复杂度的定义,可扩容数组实现的栈为O(1);
  • 空间复杂度:出入栈时只需要一两个临时变量存储空间O(1),是指存储数据之外,算法运算需要的额外存储空间;
  1. 链表实现(时间和空间复杂度都是O(1))

栈的应用

  1. 栈在函数调用中的应用:操作系统给每个线程分配了一块独立的内存空间,这块内存空间被组织成栈这种结构,用来存储函数调用时的临时变量。每进入一个函数,就会将其中的临时变量作为栈帧入栈,当被调用的函数执行完成,返回之后,讲这个函数对应的栈帧出栈。
  2. 栈在表达式求值(比如:34+13*9+44-12/13)中的应用:利用两个栈,其中一个用来保存操作,另一个用来保存运算符。我们从左向右遍历表达式,当遇到数字我们就压入操作数栈;当遇到运算符,就与运算符栈的栈顶元素进行比较,若比运算符栈顶元素的优先级高,就当将当前运算符压入栈;若比运算符栈顶元素优先级低或者相同,从运算符中取出栈顶运算符,从操作数栈顶取出2个操作数,然后进行计算,把计算完的结果压入操作数栈,继续比较。
  3. 栈在括号匹配(比如{[]{}})中的应用:用栈保存为匹配的左括号,从左到右依次扫描字符串,当扫描到左括号时,则将其压入栈中;当扫描到右括号时,从栈顶取出一个左括号,如果能匹配上,则继续扫描剩下的字符串。如果扫描过程中,遇到不能配对的右括号,或者栈中没有数据,则说明为非法格式。当所有的括号都扫描完成之后,如果栈为空,就说明字符串合法;反之字符串非法。
  4. 如何实现浏览器的前进和后退功能:我们使用两个栈X和Y,我们把首次浏览的页面依次压入X,当点击后退按钮时,再次依次从栈X中出栈,并将出栈的页面依次放入Y栈。当栈X中没有数据时,说明没有页面可以浏览后退浏览了。当Y栈没有数据,那就说明没有页面可以点击前进浏览了。

《数据结构与算法之美》 -- 王争

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序是一种基于数组实现的,它的特点是具有随机存取的特性。顺序的基本运算包括进、出和查看顶元素。进操作将元素插入到顶,出操作将顶元素删除并返回,查看顶元素操作返回顶的元素值,但不修改的状态。 在C语言中,顺序的存储结构可以使用一个一维数组来存放中的元素,同时使用一个指示器top来指示顶的位置。在进行进和出操作时,需要更新top的值,使其指向顶元素。 下面是一种常见的顺序定义和基本操作的示例代码: ```c // 定义中元素的数据类型 typedef int StackElementType; // 定义顺序的存储结构 #define Stack_Size 100 // 的最大容量 typedef struct { StackElementType elem[Stack_Size]; // 用数组存放中元素 int top; // 顶指针 } SeqStack; // 初始化顺序 void Init_SeqStack(SeqStack *S) { S->top = -1; // 初始时为空,顶指针置为-1 } // 进操作 void Push_SeqStack(SeqStack *S, StackElementType x) { if (S->top == Stack_Size - 1) { printf("已满,无法进"); return; } S->top++; // 顶指针加1 S->elem[S->top] = x; // 将新元素放入顶位置 } // 出操作 StackElementType Pop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空,无法出"); return -1; // 返回一个特殊值表示出错 } StackElementType x = S->elem[S->top]; // 获取顶元素的值 S->top--; // 顶指针减1 return x; // 返回顶元素的值 } // 查看顶元素 StackElementType GetTop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空"); return -1; // 返回一个特殊值表示出错 } return S->elem[S->top]; // 返回顶元素的值 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值