【Js数据结构——栈】

2. 栈

栈 是一个遵从 后进先出 原则的有序集合。

2.1 基于数组的 Stack

class Stack {
    constructor(){
        this.items = [];
    }
    
    // 插入元素
    push(value){
        this.items.push(value);
    }
    
    // 删除栈顶元素
    pop(){
        let val = this.items[this.items.length - 1];
        this.items.pop()
        return val;
    }

    // 查看栈顶元素
    peek(){
        return this.items[this.items.length - 1];
    }

    // 清空栈
    clear(){
        this.items = [];
    }

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

    // 栈的大小
    size(){
        return this.items.length;
    }
}

2.2 基于JS对象的 Stack

 this.items = {}; // key:value
    }

    push(value){
        // console.log(typeof this.count);
        this.items[this.count] = value;
        this.count ++;
    }

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

        return val;
    }

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

    size(){
        return this.count;
    }

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

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

    // 数组有自己的toString方法,所以不用关心。
    toString(){
        if(this.isEmpty()){
            return '';
        }
        let objString = `${this.items[0]}`;
        console.log(objString);

        for(let i = 1; i < this.count; i ++){
            objString = `${objString},${this.items[i]}`
        }

        return objString;
    }
}

2.3 保护数据结构内部元素

let s = new Stack()
s.push(12);
s.push(11);
console.log(s);
console.log(Object.getOwnPropertyNames(s)); // [ 'count', 'items' ]
console.log(Object.keys(s)); // [ 'count', 'items' ]
console.log(s.items); // { '0': 12, '1': 11 }

表明 count items 属性是公开的,并没有得到保护。


2.3.1 下划线命名约定

class Stack{
    constructor(){
        this._count = 0;
        this._items = {}; 
    }
}

这种方式只是一种约定,不能保护数据。

2.3.2 用ES6的限定作用域 Symbol 实现

const _items = Symbol('stackItems');

class Stack{
    constructor(){
        // 访问形式!
        this[_items] = [];
    }

    push(value){
        this[_items].push(value);
    }
}

console.log(_items); // Symbol(stackItems)
console.log(typeof _items); // Symbol

const s = new Stack()
s.push(12);
s.push(223);
console.log(s); // Stack { [Symbol(stackItems)]: [ 12, 223 ] }

let sy = Object.getOwnPropertySymbols(s);
console.log(sy); // [ Symbol(stackItems) ]
console.log(sy[0]); // [ Symbol(stackItems) ]
s[sy[0]].push(88); // Symbol(stackItems) !!! 可以访问到_items
console.log(s); // Stack { [Symbol(stackItems)]: [ 12, 223, 88 ] }

这种方法是一个假的私有属性。

因为Object.getOwnPropertySymbols()该方法可以取得类里面声明的所有 Symbols属性。


2.3.3 用ES6的WeakMap实现类

  • WeakMap 可以存储键值对。
  • 实现了真正的属性私有,但是代码可读性不强。
const items = new WeakMap();

class Stack{
    constructor(){
        items.set(this, []); // key: value | (this: [])
    }

    push(value){
        const s = items.get(this);
        s.push(value);
    }

    pop(){
        const s = items.get(this); // typeof s == arr
        return s.pop();
    }
}

2.4 进制转换

2.4.1 十进制转二进制

function decimalToBinary(value){
    const restStack = new Stack(); // 放余数
    console.log(restStack);
    let number = value;
    let rem = 0; 
    let binaryString = ''

    while(number > 0){
        rem = Math.floor(number % 2);
        number = Math.floor(number / 2);
        restStack.push(rem);
    }

    // output
    while(!restStack.isEmpty()){
        binaryString += restStack.pop()
    }

    return binaryString;
}

console.log(decimalToBinary(10));

2.4.2 进制转换算法

/*  
    params: decValue, base(几进制)
*/
function baseConver(decValue, base){
    const restStack = new Stack(); // 放余数
    const digitis = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';

    let number = decValue;
    let rem = 0; 
    let baseString = ''

    if(!(base >= 2 && base <= 36)){
        return '';
    }

    while(number > 0){
        rem = Math.floor(number % base);
        number = Math.floor(number / base);
        restStack.push(rem);
    }

    // output
    while(!restStack.isEmpty()){
        baseString += digitis[restStack.pop()];
    }

    return baseString;
}

console.log(baseConver(100345, 35));
console.log(baseConver(16, 4));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值