JavaScript数据结构与算法之 "栈"

栈数据结构简介

  • 栈是一种遵循先进后出原则的数据结构
  • 新添加或待删除的元素都位于栈的同一端称为栈顶,另一端称为栈底
  • 在栈里新元素都靠近栈顶,旧元素都靠近栈底
  • 栈在现实生活中类似于:一叠书,一叠盘子
  • 栈在编程语言中多用于管理变量,方法的调用,同时也用于管理浏览器的历史记录(浏览器的返回按钮)

通过数组实现栈

  • 通过数组的 push 和 pop 方法,JavaScript可以实现名为栈的数据结构
  • 通过数组实现的栈的方法:
    • push(element(s)): 添加一个或几个新元素到栈顶
    • pop(): 删除栈顶的元素,同时返回被删除的元素
    • peek() :返回栈顶的元素,但不对栈做任何修改
    • isEmpty(): 判断栈里是否有元素,有则返回true,没有则返回false
    • clear(): 清除栈里的所有元素
    • size(): 返回栈里的元素个数,该方法和数组的length属性很类似
  • 代码:
    /*表示栈的类*/
    class Stack {
        constructor() {
            this.items = [];  // items 数组存储栈中的元素
        }
    
        // push(element(s)): 添加一个或几个新元素到栈顶
        push(element) {
            this.items.push(element);
        }
    
        // pop(): 删除栈顶的元素,同时返回被删除的元素
        pop() {
            return this.items.pop();
        }
    
        // peek() :返回栈顶的元素,但不对栈做任何修改
        peek() {
            return this.items[this.items.length - 1];
        }
    
        // isEmpty(): 判断栈里是否有元素,有则返回true,没有则返回false
        isEmpty() {
            return this.items.length === 0;
        }
    
        // clear(): 清除栈里的所有元素
        clear() {
            this.items = [];
        }
    
        // size(): 返回栈里的元素个数,该方法和数组的length属性很类似
        size() {
            return this.items.length;
        }
    }
    

通过对象实现栈

  • 通过对象来实现栈,会占用更少的内存空间,同时也跟高效
  • 通过对象实现的栈的方法:
    • push(element): 添加一个新元素到栈顶
    • pop(): 删除栈顶的元素,同时返回被删除的元素
    • peek() :返回栈顶的元素,但不对栈做任何修改
    • isEmpty(): 判断栈里是否有元素,有则返回true,没有则返回false
    • clear(): 清除栈里的所有元素
    • size(): 返回栈里的元素个数,该方法和数组的length属性很类似
    • toString()
  • 代码:
    /*表示栈的类*/
    class Stack {
        constructor() {
            this.items = {};  // items 对象存储栈中的元素
            this.count = 0;  // count 表示栈中元素的数量
        }
    
        // push(element): 添加一个新元素到栈顶
        push(element) {
            this.items[this.count] = element;
            this.count += 1;
        }
    
        // pop(): 删除栈顶的元素,同时返回被删除的元素
        pop() {
            if (this.isEmpty()) {
                return undefined;
            }
    
            this.count -= 1;
            const result = this.items[this.count]; //存储栈顶的元素
            delete this.items[this.count]; //删除栈顶的元素
            return result;
        }
    
        // peek() :返回栈顶的元素,但不对栈做任何修改
        peek() {
            if (this.isEmpty()) {
                return undefined;
            }
    
            return this.items[this.count - 1];
        }
    
        // isEmpty(): 判断栈里是否有元素,有则返回true,没有则返回false
        isEmpty() {
            return this.count === 0;
        }
    
        // clear(): 清除栈里的所有元素
        clear() {
            this.items = {};
            this.count = 0;
        }
    
        // size(): 返回栈里的元素个数,该方法和数组的length属性很类似
        size() {
            return this.count;
        }
    
        // toString()
        toString() {
            if (this.isEmpty()) {
                return '';
            }
    
            let str = `${this.items[0]}`;
            for (let i = 1; i < this.count; i += 1) {
                str = `${str},${this.items[i]}`;
            }
    
            return str;
        }
    }
    

栈的运用

进制转换算法

  • 将十进制转换成基数为2~36的任意进制
  • 代码:
    const baseConverter = (decNumber, base) => {
        const remStack = new Stack(); // 存储余数的栈
        let number = decNumber;  // 十进制数
        let rem;  // 余数
        let str = ''; // 最终输出结果字符串
    
        // 如果不是转换成 2~36 进制数
        if (!(base >= 2 && base <= 36)) {
            return '';
        }
    
        // 转换成 2~32 进制数
        while (number > 0) {
            rem = Math.floor(number % base);
            remStack.push(rem);
            number = Math.floor(number / base);
        }
    
        // 生成base进制的字符串
        const digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        while (!remStack.isEmpty()) {
            str += digits[remStack.pop()];
        }
    
        return str;
    };
    
    
    console.log(baseConverter(100345, 2));      // 结果:11000011111111001
    console.log(baseConverter(100345, 8));      // 结果:303771
    console.log(baseConverter(100345, 16));     // 结果:187F9
    console.log(baseConverter(100345, 35));     // 结果:2BW0
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值