我想知道为什么我们甚至应该使用堆栈,因为数组或链表可以完成堆栈所能做的一切?为什么我们要把它单独命名为"数据结构"?在现实世界中,仅仅使用一个数组就足以解决问题;为什么要麻烦实现一个堆栈,它将限制自己只能从集合的顶部推送和弹出?
我认为最好使用术语数据类型来指代其行为由某些接口、代数或操作集合定义的事物。之类的东西
- 烟囱
- 队列
- 优先级队列
- 出队列
- 列表
- 套
- 层次结构
- 地图(字典)
是类型,因为对于每种类型,我们只列出它们的行为。堆叠是堆叠,因为它们只能被推动和弹出。队列是队列,因为。。。(你明白了)。
另一方面,数据结构是由其排列组件的方式定义的数据类型的实现。示例包括
- 数组(按索引进行恒定时间访问)
- 链表
- 位图
- BST
- 红黑树
- (a,b)-树木(例如2-3棵树)
- 跳过列表
- 哈希表(多种变体)
- 邻接矩阵
- Bloom过滤器
- Judy阵列
- 尝试
很多人确实混淆了数据结构和数据类型这两个术语,但最好不要太迂腐。堆栈是数据类型,而不是数据结构,但是,为什么太迂腐呢。
为了回答您的具体问题,在我们希望确保或仅通过推送和弹出来修改数据的情况下,我们使用堆栈作为数据类型,并且我们从未违反此访问模式(即使是意外)。
在这种情况下,我们可以使用链表作为堆栈的实现。但大多数编程语言都会提供一种限制接口的方法,使我们的代码能够以后进先出的方式可读、安全地使用我们的数据。
TL;DR:可读性。安全
堆栈可以而且通常使用数组或链表作为底层结构来实现。使用Stack有很多好处。
其中一个主要好处是通过推送/弹出操作维护的后进先出法排序。这允许堆栈元素具有自然顺序,并以与添加顺序相反的顺序从堆栈中移除。这种数据结构在许多应用中非常有用,在这些应用中,仅使用数组或链表实际上效率较低和/或更复杂。其中一些应用程序是:
- 符号的平衡(如括号)
- 中缀到后缀的转换
- 后缀表达式的求值
- 实现函数调用(包括递归)
- 跨度的查找(在股票市场中查找跨度)
- 网页浏览历史记录(返回按钮)
- 在文本编辑器中撤消序列
- HTML和XML中的匹配标记
Here are some more stack applications
And some more...
数组或链表的两个底层实现为堆栈提供了不同的功能和特性。这里有一个简单的比较:
(动态)阵列实现:
1. All operations take constant time besides push().
2. Expensive doubling operation every once in a while.
3. Any sequence of n operations (starting from empty stack) -> "amortized" bound takes time proportional to n.
链表实现:
1. Grows and shrinks easily.
2. Every operation takes constant time O(1).
3. Every operation uses extra space and time to deal with references.