【算法学习】JavaScript数据结构与算法-栈

495 阅读4分钟

前言

做程序员的第3个年头,从一名切图仔逐渐成为公司开发的主力,随着业务的深入和经验的积累,算法的学习提上了日程。

从今天开始,我将把平时项目中积累的经验和JavaScript算法结合起来出一个系列的文章,总结学习心得的同时希望能帮助到后面学习算法的同学!

我是Asscre,每周两篇算法相关经验分享,如果你也有兴趣,那我们一起互相监督催更哈!

点赞+关注,永远不迷路!

JavaScript算法之栈

首先,我们得先了解什么是栈:

栈(stack)是一种运算受限的线性表:

  • LIFO(last in first out)表示就是后进入的元素,第一个弹出栈空间。类似于自动餐托盘,最后放上的托盘,往往先把拿出去使用。
  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对的,把另一端称为栈底。
  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

特点:先进后出,后进先出

如图所示:

image.png

image.png

栈结构实现

对于栈的实现,我们有两种方式,一种是class实现,一种是函数式实现。

首先,我们先定义一下的方法
  • push() 添加一个新元素到栈顶位置。
  • pop() 移除栈顶的元素,同时返回被移除的元素。
  • peek() 返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它)。
  • isEmpty() 如果栈里没有任何元素就返回 true,否则返回 false
  • size() 返回栈里的元素个数。这个方法和数组的 length 属性类似。
  • toString() 将栈结构的内容以字符串的形式返回。
下面我们基于数组来分别实现这两种栈的实现:
  • class实现
class StackClass {
    // 构造函数
    constructor() {
        // 初始化一个数组,this指向new Stack的实例对象
        this.items = [];
    }

    // push(item) 压栈操作,往栈里面添加元素
    push(item) {
        this.items.push(item);
    }

    // pop() 出栈操作,从栈中取出元素,并返回取出的那个元素
    pop() {
        return this.items.pop();
    }

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

    // isEmpty() 判断栈是否为空
    isEmpty() {
        return this.items.length === 0;
    }

    // size() 获取栈中元素个数
    size() {
        return this.items.length;
    }

    // toString() 返回以字符串形式的栈内元素数据
    toString() {
        let full_string = '';
        for (let item of this.items) {
            full_string += item + ' ';
        }
        return full_string;
    }
}
  • function实现
function StackFunction() {
    // 初始化一个数组,用于栈处理
    this.items = [];
    
    // push(item) 压栈操作,往栈里面添加元素
    Stack.prototype.push = (item) => {
        this.items.push(item);
    }
    
    // pop() 出栈操作,从栈中取出元素,并返回取出的那个元素
    Stack.prototype.pop = (item) => {
        this.items.pop(item);
    }
    
    // peek() 查看栈顶元素
    Stack.prototype.peek = () => {
        // 获取到最顶部的元素并返回
        return this.items[this.items.length - 1] || -1;
    }

    // isEmpty() 判断栈是否为空
    Stack.prototype.isEmpty = () => {
        return this.items.length === 0;
    }

    // size() 获取栈中元素个数
    Stack.prototype.size = () => {
        return this.items.length;
    }

    // toString() 返回以字符串形式的栈内元素数据
    Stack.prototype.toString = () => {
        let full_string = '';
        for (let item of this.items) {
            full_string += item + ' ';
        }
        return full_string;
    }
}
  • 对栈结构测试
// 对class栈结构测试
const stackClass = new StackClass();
// push() 测试
stackClass.push(1);
stackClass.push(2);
stackClass.push(3);
console.log(stackClass.items); //--> [1, 2, 3]
// pop() 测试
console.log(stackClass.pop()); //--> 3
// peek() 测试
console.log(stackClass.peek()); //--> 2
// isEmpty() 测试
console.log(stackClass.isEmpty()); //--> false
// size() 测试
console.log(stackClass.size()); //--> 2
// toString() 测试
console.log(stackClass.toString()); //--> 1 2


// 对function栈结构测试
const stackFunction = new StackFunction()
stackFunction.push(1)
stackFunction.push(2)
stackFunction.push(3)
stackFunction.push(4)
console.log(stackFunction.items); //--> [1, 2, 3, 4]
// pop() 测试
stackFunction.pop() //--> 4
// peek() 测试
console.log(stackClass.peek()); //--> 3
// isEmpty() 测试
console.log(stackFunction.isEmpty()) //--> false
// size() 测试
console.log(stackFunction.size()) //--> 3
console.log(stackFunction) //--> [1, 2, 3]
// toString() 测试
console.log(stackFunction.toString()) //--> 1 2 3

程序中的栈应用

  • LeetCode:栈排序

编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:push、pop、peek 和 isEmpty。当栈为空时,peek 返回 -1。

var SortedStack = function() {
    this.items = [];
};

/** 
 * @param {number} val
 * @return {void}
 */
SortedStack.prototype.push = function(val) {
    this.items.push(val);
    for(let i = this.items.length-1, tmp; i > 0; i--){
        if(this.items[i] > this.items[i-1]){
            tmp = this.items[i];
            this.items[i] = this.items[i-1];
            this.items[i-1] = tmp;
        }else{
            break;
        }
    }
};

/**
 * @return {void}
 */
SortedStack.prototype.pop = function() {
    this.items.pop();
};

/**
 * @return {number}
 */
SortedStack.prototype.peek = function() {
    return this.items[this.items.length - 1] || -1;
};

/**
 * @return {boolean}
 */
SortedStack.prototype.isEmpty = function() {
    return this.items.length === 0;
};

/**
 * Your SortedStack object will be instantiated and called as such:
 * var obj = new SortedStack()
 * obj.push(val)
 * obj.pop()
 * var param_3 = obj.peek()
 * var param_4 = obj.isEmpty()
 */
  • 十进制转二进制
// 十进制转二进制代码
function dec2bin(dec_num) {
    const stack = new StackFunction()
    console.log(stack)
    while (dec_num > 0) {
        // 获取余数,放到栈中
        // console.log(dec_num % 2)
        stack.push(dec_num % 2)
        // 获取整除后的结果
        dec_num = Math.floor(dec_num / 2)

    }
    // 从栈中取出0和1
    let binary_str = ''
    while (! stack.isEmpty()) {
        binary_str += stack.pop()
    }
    return binary_str
}
console.log(dec2bin(100)) //-->1100100 

好了,今天的分享就到这里了。热爱学习的你记得:点赞👍关注哦 感谢支持!!

我是Asscre,我们两天后见哦!

2021年7月22日 00:20 偶有阵雨🌦️,台风天 我在珠海。

内蒙古加油!郑州加油!