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
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章