数据结构——栈结构

149 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

什么是栈结构

栈是一种非常常见的数据结构,在程序中应用是很广泛的。

大家都了解数组,数组是一种线性结构,且可以在数组的任意位置插入和删除数据。但为了实现某些功能,必须对这种任意性加以限制。而栈和队列就是比较常见的受限的线性结构。

如何形象的理解栈?比如我们在生活中摞在一起的盘子,平时放盘子时候,都是从下往上一个一个的放,而取得时候,我们则是从上往下一个一个的依次取,而不能从中任意抽出。

这种后进者先出,先进者后出,就是一个很典型的栈结构

栈结构的示意图

image.png

栈的特点

栈(stack),是一种受限的线性表,后进后出(LIFO)

  • 其限制是仅允许在空间的一端进行插入和删除运算。这一端被称为栈顶,相对的,另一端称为栈地。
  • LIFO(last in first out)就是后进入的元素,第一个弹出栈空间。
  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素
  • 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

栈的实现

实现栈结构一般有两种比较常见的方式:

  • 基于数组的实现
  • 基于链表的实现。

由于JS中没有自带链表,因此我们实现的栈结构是基于数组的。

栈都有哪些操作

  • push(element): 添加一个新元素到栈顶位置。
  • pop(): 移出栈顶的元素,同时返回被移除的元素。
  • peek(): 返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返回它)。
  • isEmpty(): 如果栈里没有任何元素就返回true,否则返回false。
  • size(): 返回栈里的元素个数,这个方法和数组的lenght属性很类似。
  • toString(): 将栈结构的内容以字符形式返回。

代码实现:

function Stack() {
            // 栈中的属性
            this.items = [];

            // 栈的相关操作
            // 1. 将元素压入栈
            Stack.prototype.push = function (element) {
                this.items.push(element);
            }
            // 2. 从栈中取出元素
            Stack.prototype.pop = function () {
                return this.items.pop();
            }
            // 3. 查看栈顶元素
            Stack.prototype.peek = function () {
                return this.items[this.items.length - 1];
            }

            // 4. 判断栈是否为空
            Stack.prototype.isEmpty = function () {
                return this.items.length === 0;
            }
            // 5. 获取栈中元素的个数
            Stack.prototype.size = function () {
                return this.items.length;
            }

            // 6. toString
            Stack.prototype.toString = function () {

                return this.items.join(' ');
            }
        }

栈的应用

  • 浏览器的前进、后退功能。

当依次访问a-b-c页面之后,点击浏览器的后退按钮,就可以查看之前浏览过的页面b和a。当后退到页面a,再点击前进按钮,就可以重新查看页面b和c。但是,如果后退到b页面后,点击了新的页面d,则不管前进还是后退都无法查看c页面了。

  • 函数调用栈

操作系统给每个线程分配了一块独立的内存空间,这块内存被组织成“栈”这种结构,用来存储函数调用时的临时变量。每进入一个函数,就会将临时变量作为一个栈帧入栈,当被调用函数执行完成,返回之后,再将这个函数对应的栈帧出栈。

总结

  • 栈是一种操作受限的线性数据结构,只支持入栈和出栈的操作,最大的特点就是元素后进后出。
  • 栈既可以用数组是实现,也可以使用链表实现。