js数据结构之有序栈

479 阅读2分钟

是一种比较常见的数据结构,虽然在js中没有原生的栈,但是实现起来也并不复杂,主要就是pushpoptop几个函数的实现。我这里说到的有序栈就是一种元素按照一定顺序排列的。主要的应用场景有:求数组中最小的K个数等。 有序栈的类实现方式

class Stack{
    /**
     * 构造函数,s用来存储数据,count用来记录栈的大小
     */
    constructor(){
        this.s = [];
        this.count = 0;
    }

    /**
     * 栈的push函数,往栈中添加数据
     * @param num 需要存储到栈中的数据
     */
    push(num) {
        // 如果数据为空,不做操作
        if(!num) return;
        // 找到栈中大于num的数的下标
        const index = this.s.findIndex((value, index) => value > num);
        // 如果没有找到,说明栈中的元素都会小于num,直接添加到数组的最后面
        if(index === -1) this.s.push(num);
        else{
            // 否则,插入第一个会大于num的元素位置
            this.s.splice(index, 0, num);
        }
        // 栈大小增加1
        ++this.count;
    }

    /**
     * 栈弹出元素,数组按从小到大排序的,直接把最大的元素弹出
     */
    pop(){
        this.s.pop();
        --this.count;
    }

    /**
     * 返回栈顶元素
     * @returns 数组中最大的元素
     */
    top() {
        if(this.count >= 1) return this.s[this.count-1];
        return undefined;
    }
}

function kMin(arr, k){
    const st = new Stack();
    arr.forEach(item => {
        // 如果栈的元素个数小于k,直接将数据添加到栈中
        if(st.count < k){
            st.push(item);
        }else{
            // 否则的话,如果元素小于栈顶元素,则将栈顶元素弹出,并将数据添加到栈中
            if(item < st.top()){
                st.pop();
                st.push(item);
            }
        }
    })
    return st.s;
}

kMin([7,4,5,8,10,30], 2)

现在函数式编程比较流行,这里再给出函数式的实现方式。明显可以看出,函数式的实现方式更加简洁明了,对外暴露的变量和函数都通过return的方式。

function fStack(){
    const arr = [];

    const count = () => {
        return arr.length;
    }

    const push = (num) => {
        // 如果数据为空,不做操作
        if(!num) return;
        // 找到栈中大于num的数的下标
        const index = arr.findIndex((value, index) => value > num);
        // 如果没有找到,说明栈中的元素都会小于num,直接添加到数组的最后面
        if(index === -1) arr.push(num);
        else{
            // 否则,插入第一个会大于num的元素位置
            arr.splice(index, 0, num);
        }
    }

    const pop = () => {
        arr.pop();
    }

    const top = () => {
        if(count >= 1) return arr[count-1];
        return undefined;
    }

    return {
        arr,
        count,
        push,
        pop,
        top
    }
}

function kMin(arr, k){
    const st = new fStack();
    arr.forEach(item => {
        // 如果栈的元素个数小于k,直接将数据添加到栈中
        if(st.count() < k){
            st.push(item);
        }else{
            // 否则的话,如果元素小于栈顶元素,则将栈顶元素弹出,并将数据添加到栈中
            if(item < st.top()){
                st.pop();
                st.push(item);
            }
        }
    })
    return st.arr;
}

const res = kMin([7,4,5,8,10,30], 2)