数据结构与算法(二)

141 阅读2分钟

栈是什么?

  • 一个后进先出的受限线性结构
  • JavaScript中没有栈,但可以用 Array 实现栈的所有功能 image.png
  • Array 的 push 和 pop 方法来实现后进先出
const stack = []
// 入栈顺序 1,2
stack.push(1)
stack.push(2)

// 出栈顺序 2,1
stack.pop()
stack.pop()

栈的应用场景有哪些?

  • 十进制转二进制
  • 判断字符串的括号是否有效
  • 函数调用堆栈

数组Array实现栈功能

class Stack {
    constructor() {
        this.items = [];
    }

    // 入栈操作
    push(element) {
        this.items.push(element);
    }

    // 出栈操作
    pop() {
        if (this.isEmpty()) {
            return null;
        }
        return this.items.pop();
    }

    // 查看栈顶元素
    peek() {
        if (this.isEmpty()) {
            return null;
        }
        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();
stack.push(10);
stack.push(20);
stack.push(30);

console.log(stack.peek()); // 输出: 30
console.log(stack.pop());  // 输出: 30
console.log(stack.size()); // 输出: 2
console.log(stack.isEmpty()); // 输出: false
stack.clear();
console.log(stack.isEmpty()); // 输出: true    

基于上面实现的栈,进一步实现十进制转二进制功能

/**
基本思路是不断地将十进制数除以 2,把余数压入栈中,直到商为 0,然后依次弹出栈中的元素,就得到了二进制数。
*/
function decimalToBinary(decimalNumber) {
    const stack = new Stack();
    let number = decimalNumber;
    let binaryString = '';

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

    while (!stack.isEmpty()) {
        binaryString += stack.pop();
    }

    return binaryString === '' ? '0' : binaryString;
}

// 测试示例
const decimal = 10;
const binary = decimalToBinary(decimal);
console.log(`十进制数 ${decimal} 转换为二进制是: ${binary}`);

基于上面实现的栈,进一步实现字符串括号匹配功能

/**
基本思路:基本思路是遍历字符串,遇到左括号时将其压入栈中,遇到右括号时从栈中弹出一个左括号进行匹配,
如果匹配成功则继续遍历,若栈为空或者匹配失败则说明括号无效,遍历结束后若栈为空则说明所有括号都有效匹配。
*/
function isValidBrackets(s) {
    const stack = new Stack();
    const mapping = {
        ')': '(',
        ']': '[',
        '}': '{'
    };

    for (let i = 0; i < s.length; i++) {
        const char = s[i];
        if (Object.values(mapping).includes(char)) {
            // 如果是左括号,压入栈中
            stack.push(char);
        } else if (Object.keys(mapping).includes(char)) {
            // 如果是右括号
            const topElement = stack.pop();
            if (topElement!== mapping[char]) {
                return false;
            }
        }
    }

    // 遍历结束后栈为空则括号有效
    return stack.isEmpty();
}

// 测试示例
const str1 = "()[]{}";
const str2 = "([)]";
console.log(`字符串 "${str1}" 的括号是否有效: ${isValidBrackets(str1)}`);
console.log(`字符串 "${str2}" 的括号是否有效: ${isValidBrackets(str2)}`);