重学JavaScript数据结构之 “栈”

127 阅读1分钟

1.什么是栈

栈是一种遵循后进先出(LIFO)原则的有序集合。新添加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就叫栈底。

2.栈的方法

我们需要一种数据结构来保存栈里的元素,可以是数组or对象,这里我们以数组为例子,下面我们创建一个类来表示栈:

class myStack {
    constructor() {
        this.items = [];
    }
}

由于栈遵循后进先出(LIFO)的原则,所以我们需要对栈内元素的添加和删除做一些限制,以下是栈内的方法:

push(item(s?)): 添加一个或者多个元素到栈中。
pop(): 删除栈顶的元素,同时需要返回被删除的元素。
peek(): 返回栈顶的元素,但不对栈进行任何的修改。
isEmpty(): 判断栈是否为空,如果栈内无任何元素返回true,反之返回falseclear(): 移除栈内的所有元素。
size(): 返回栈内元素的个数。

现在我们可以这样表示栈:

class myStack {
    constructor() {
        this.items = [];
    }
    push(...items) {}
    pop() {}
    peek() {}
    isEmpty() {}
    clear() {}
    size() {}
}

3.栈的实现

运用数组的一些方法我们可以轻易的实现栈内的方法:

push方法

push(...items) {
    if (!items.length) {
        return;
    }
    for (let i = 0; i < items.length; i++) {
        this.items.push(items[i]);
    }
}

pop方法

pop() {
    return this.items.pop();
}

peek方法

peek() {
    return this.items[this.items.length - 1];
}

isEmpty方法

isEmpty() {
    return this.items.length === 0;
}

clear方法

clear() {
    this.items = [];
    // this.items.splice(0);
}

size方法

size() {
    return this.items.length;
}

完整代码如下:

class myStack {
    constructor() {
        this.items = [];
    }
    push(...items) {
        if (!items.length) {
            return;
        }
        for (let i = 0; i < items.length; i++) {
            this.items.push(items[i]);
        }
    }
    pop() {
        return this.items.pop();
    }
    peek() {
        return this.items[this.items.length - 1];
    }
    isEmpty() {
        return this.items.length === 0;
    }
    clear() {
        this.items = [];
        // this.items.splice(0);
    }
    size() {
        return this.items.length;
    }
}

4.栈的应用

栈通常用于在编程语言的编译器和内存中保存变量,方法调用等,也被用于浏览器历史记录。下面我们用栈实现一个十进制转为其他进制的方法:

function convert(toSolveNum, defaultBase = 2) {
    // base不符合直接返回
    if (defaultBase < 2 || defaultBase > 36) {
        return toSolveNum;
    }
    let result = '', divisionNumber = toSolveNum;
    // 对应 0-35
    const dights = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    const stack = new myStack();
    // 如果结果不为 0,则一直计算
    do {
        stack.push(divisionNumber % defaultBase);
    } while(divisionNumber = Math.floor(divisionNumber / defaultBase))
    // 拼接字符串
    while (!stack.isEmpty()) {
        result += dights[stack.pop()];
    }
    return result;
}