JavaScripts数据结构——栈数据结构

本文介绍了栈数据结构的基本概念,其遵循后进先出(LIFO)原则,并以数组为基础详细阐述了栈的主要操作,如push、pop、peek、isEmpty、clear和size方法。还讨论了使用数组和对象实现栈时的时间复杂度,并提到了栈在实现数制转换等场景中的应用。
摘要由CSDN通过智能技术生成

栈是一种遵从后进先出(LIFO)原则的有序集合。新增加或待删除的元素都保存在栈的同一端,称作栈顶,另一端就是栈底。在栈里,新元素都靠近栈顶,旧元素都靠近栈底。例如,一摞书或者堆放起来的碗,新增加的在最顶部,旧的在最下面放着。

我们可以创建一个基于数组的栈。数组可以在任何位置添加或删除元素,用它来保存栈里的元素最好不过。栈遵循LIFO原则,需要对元素的插入和删除功能进行限制。我们为栈声明如下方法:

  • push(element(s)): 添加一个(或几个)新元素到栈顶。
  • pop(): 移除栈顶的元素,同时返回被移除的元素。
  • peek(): 返回栈顶的元素,不对栈做任何修改,仅仅只是返回栈顶元素,不会移除它。
  • isEmpty(): 如果栈里没有任何元素就返回true,否则返回false。
  • clear(): 移除栈里的所有元素。
  • size(): 返回栈里的元素个数。类似于数组的length属性。
class Stack {
    constructor() {
        this.items = [];
    }

    push(element) {
        this.items.push(element);
    }

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

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

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

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

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

// 实例化一个栈
const stack = new Stack();
console.log(stack.isEmpty()); // true
stack.push(5);
stack.push(8);
console.log(stack.peek()); // 8
stack.push(10);
console.log(stack.size()); // 3
console.log(stack.isEmpty()); // false
stack.pop();
stack.pop();
console.log(stack.size()); // 1

 使用数组来存储元素,栈的大部分方法的时间复杂度是O(n),因为最糟糕的情况下,我们需要迭代数组的所有位置才能找到我们要找的元素。如果数组长度更长,所需的时间会更长。

我们也可以使用一个对象来存储所有的栈元素,除了toString()方法,其他方法的复杂度均为O(1),我们可以直接找到目标元素进行操作。

 

class Stack = {
    constructor() {
        this.count = 0;
        this.items = {};
    }

    push(element) {
        this.items[this.count] = element;
        this.count++;
    }

    size() {
        return this.count;
    }

    isEmpty() {
        return this.count === 0;
    }

    pop() {
        if (this.isEmpty()) {
            return undefined;
        }
        this.count--;
        const result = this.items[this.count];
        delete this.items[this.count];
        return result;
    }

    peek() {
        if(this.isEmpty()) {
            return undefined;
        }
        return this.items[this.count - 1];
    }

    clear() {
        this.items = {};
        this.count = 0;
    }

    toString() {
        if(this.isEmpty()) {
            return '';
        }
        let objString = `${this.items[0]}`;
        for(let i=1; i< this.count; i++) {
            objString = `${objString},${this.items[i]}`;
        }
        return objString;
    }
}

const stack = new Stack();
stack.push(2);
stack.push(5);
console.log(stack.toString()); // 2,2,5

栈的应用:实现十进制的数转换为2~36任意进制的值。我们使用上边定义的Stack类实现。

function baseConverter(decNumber, base) {
    // 实例化余数栈,使用上文的Stack类
    const remStack = new Stack();
    // 余数对应的字符
    const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    // 要转换的数字
    let number = decNumber;
    // 余数
    let rem;
    // 转换后的字符串
    let baseString = '';
    // 判断base在不在规则内
    if(!(base >= 2 && base <= 36)) {
        return '';
    }
    while(number > 0) {
        rem = Math.floor(number % base);
        remStack.push(rem);
        number = Math.floor(number / base);
    }

    while(!remStack.isEmpty()) {
        baseString += digits[remStack.pop()];
    }

    return baseString;
}
console.log(baseConverter(10, 2)); // 1010
console.log(baseConverter(100345, 2)); // 11000011111111001
console.log(baseConverter(100345, 8)); // 303771
console.log(baseConverter(100345, 16)); // 187F9
console.log(baseConverter(100345, 35)); // 2BW0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值