棧數據結構簡介
- 棧是一種遵循先進後出原則的數據結構
- 新添加或待刪除的元素都位於棧的同一端稱爲棧頂,另一端稱爲棧底
- 在棧裏新元素都靠近棧頂,舊元素都靠近棧底
- 棧在現實生活中類似於:一疊書,一疊盤子
- 棧在編程語言中多用於管理變量,方法的調用,同時也用於管理瀏覽器的歷史記錄(瀏覽器的返回按鈕)
通過數組實現棧
- 通過數組的 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