JavaScript数据结构 - 栈

前言

若是你问我,人可否改变本身的命运,我也不晓得。但我晓得,不认命,就是咱们这代人的命。javascript

  1. 基础知识就像是一座大楼的地基,它决定了咱们的技术高度。
  2. 咱们应该多掌握一些可移值的技术或者再过十几年应该都不会过期的技术,数据结构与算法就是其中之一。

正文

栈的使用遍及程序语言实现的方方面面,从表达式求值处处理函数调用。java

栈(stack) 是限定在表尾进行插入或删除操做的线性表。所以,对栈来讲,表尾端有其特殊含义,称为 栈顶(top) ,相应地,表头端称为 栈底(bottom) 。不含元素的空表称为空栈。node

栈的定义

  1. 后进者先出,先进者后出,简称 后进先出(LIFO) ,这就是典型的 结构。
  2. 新添加的或待删除的元素都保存在栈的末尾,称为 栈顶 ,另外一端就叫 栈底
  3. 插入通常称为 入栈(push) ,删除则称为 出栈(pop)
  4. 在栈里,新元素都靠近栈顶,旧元素都靠近栈底。
  5. 从栈的操做特性来看,是一种 操做受限 的线性表,只容许在一段插入和删除数据。
  6. 不包含任何元素的栈称为 空栈

栈的实现

从数据存储的角度看,实现栈有两种方式,一种是以数组作基础,一种是以链表作基础。算法

栈的方法:数组

操做 方法
入栈 push(el)
出栈 pop()
取栈顶元素 peek()
判断是否为空栈 isEmpty()
返回栈大小 size()
清空栈 clear()

顺序栈

这里采用的是数组做为其存储数据的底层数据结构。bash

用数组 _data 保存栈内元素,构造函数将其初始化为一个空数组。数据结构

class Stack {
    constructor() {
        this._data = [];
    }
    push(el) {  // 添加新元素到栈顶
        this._data.push(el);
    }
    pop() {     // 移除栈顶元素,同时返回被移除的元素
        return this._data.pop();
    }
    peek() {    // 查看栈顶元素
        return this._data[this._data.length - 1];
    }
    isEmpty() { // 判断是否为空栈
        return this._data.length === 0;
    }
    clear() {   // 清空栈
        this._data = [];
    }
    size() {    // 查询栈的大小
        return this._data.length;
    }
    // 非必重写方法,仅供测试使用
    // 重写 JavaScript 对象默认的 toString() 方法
    // toString() {
    // return this._data.toString();
    // }
}
复制代码

链栈

这里采用的是链表做为其存储数据的底层数据结构。函数

链式栈是一种数据存储结构,能够经过单链表的方式来实现,使用链式栈的优势在于它可以克服用数组实现的顺序栈空间利用率不高的特色,可是须要为每一个栈元素分配额外的指针空间用来存放指针域。测试

function Stack() {
    this._top = null;
    this._len = 0;
}
Stack.prototype = {
    constructor: Stack,
    __Node__: function(el) {
        this.data = el;
        this.next = null;
    },
    push: function(el) {      // 添加新元素到栈顶
        const __node__ = new this.__Node__(el);
        __node__.next = this._top;
        this._top = __node__;
        this._len++;
    },
    pop: function() {       // 移除栈顶元素,同时返回被移除的元素
        if(this._top == null) return;
        const node = this._top;
        this._top = node.next;
        this._len--;
        return node.data;
    },
    peek: function() {      // 查看栈顶元素
        return this._top && this._top.data;
    },
    isEmpty: function() {   // 判断是否为空栈
        return this._top === null;
    },
    clear: function() {     // 清空栈
        this._top = null;
        this._len = 0;
    },
    size: function() {      // 查询栈的大小
        return this._len;
    },
    // 非必重写方法,仅供测试使用
    // 重写 JavaScript 对象默认的 toString() 方法
    // toString: function() {
    // let curr = this._top,
    // list = [];
    // while(curr) {
    // list.push(curr.data);
    // curr = curr.next;
    // }
    // return list.join(' -> ');
    // }
}
复制代码

上述顺序栈、链栈测试用例:this

const stack = new Stack();
stack.isEmpty();    // true
stack.push(5);      // undefined
stack.push(8);      // undefined
stack.peek();       // 8
stack.push(11);     // undefined
stack.size();       // 3
stack.isEmpty();    // false
stack.push(15);     // undefined
stack.pop();        // 15
stack.size();       // 3
stack.toString();   // 5,8,11
stack.clear();      // undefined
stack.size();       // 0
复制代码

结语

栈就是一种数据结构,他可用来解决计算机世界里的不少问题。栈是一种高效的数据结构,由于数据只能在栈顶添加或删除,因此这样的处理操做很快,并且容易实现。栈的使用遍及程序语言实现的方方面面,从表达式求值处处理函数调用等。

若是有错误或者不严谨的地方,请务必给予指正,十分感谢。

相关文章
相关标签/搜索