javascript
JavaScript数据结构与算法——栈详解
1、棧基本知識
棧是一種特殊的列表,棧的元素只能通過列表的一端訪問,這一端成為棧頂,棧具有先進(jìn)后出的特點(diǎn),要想訪問棧底的元素,就必須將上邊的元素先拿出來。對棧的操作主要是入棧和出棧,通過push()和pop()實(shí)現(xiàn)。通過pop()還能預(yù)覽棧頂元素,但是返回元素時,會將該元素從棧中刪除,所以需要引入peek()方法,返回棧頂元素,而不會將其刪除。
2、JS中棧的實(shí)現(xiàn)
從棧的基本知識可以想到,要實(shí)現(xiàn)一個棧,需要有一個數(shù)據(jù)的存儲空間(這里使用數(shù)組)、push()方法、pop()方法、peek()方法,使用top變量記錄棧頂元素,以便peek()訪問。
實(shí)現(xiàn)棧構(gòu)造函數(shù)
function Stack() {this.stack = []this.top = 0this.pop = popthis.push = pushthis.peek = peekthis.length = length // 用于返回棧元素數(shù)量this.clear = clear // 用于清空棧 }push()
function push(param) {this.stack[this.top++] = param }棧被壓進(jìn)新元素后,top++,指向下一個空位置。
pop()
function pop() {return this.stack[--this.top] }這里為什么是--this.top而不是this.top-- 呢,因?yàn)閠op初始是0,一個元素壓進(jìn)棧后,top變成了1,而stack[1]對應(yīng)的是第二個元素,此時只有一個元素,所以應(yīng)該減1,以訪問棧頂元素(邏輯為先減后訪問)。
peek()
function peek() {return this.stack[this.top - 1] }此方法用于返回棧頂元素。
length()
function length() {return this.top }用于返回棧的元素個數(shù)。
clear()
function clear() {this.top = 0 }此方法用于清空棧元素
測試實(shí)現(xiàn)的棧
測試用例
var stack = new Stack() stack.push('JavaScript') stack.push('TypeScript') stack.push('ActionScript') stack.push('CoffeeScript') console.log('棧的元素數(shù)量為: ' + stack.length()) console.log('棧頂元素為: ' + stack.peek()) console.log('進(jìn)行一次出棧操作,出棧的元素為: ' + stack.pop()) console.log('出棧后棧的元素數(shù)量為: ' + stack.length()) console.log('此時棧頂元素為: ' + stack.peek())測試結(jié)果
打開命令行工具,使用node執(zhí)行該js文件,本人為:node stack.js
運(yùn)行結(jié)果為:
3、棧應(yīng)用舉例
3.1、回文問題
之前我們探討過回文問題的解決辦法,關(guān)于回文,不太清楚含義的可以先移步本人另這篇文章,簡單點(diǎn)說就是一個字符串反轉(zhuǎn)過來仍然是原來的字符順序,比如:“A man, a plan, a canal: Panama”,忽略大小寫,忽略標(biāo)點(diǎn)符號。使用數(shù)據(jù)結(jié)合正則表達(dá)式的話,很容易解決。使用我們上邊建立的棧,應(yīng)該如何實(shí)現(xiàn)呢?
function isPalindrome(str) {// 新建一個棧var stack = new Stack()// 使用正則表達(dá)式取出句子中的字母str = str.replace(/\W/g, '').toLowerCase();// 將所有字母入棧for (var i = 0; i < str.length; i++) {stack.push(str[i])}// 出棧操作, 拼接每次出棧的字母var reverse = ''while (stack.length() > 0) {reverse += stack.pop()}// 如果入棧順序和出棧順序一致, 則為回文結(jié)構(gòu)if (str === reverse) {return true } else {return false} }原理:棧為先進(jìn)后出,進(jìn)棧順序和出棧順序一致的話,兩個字符串必定相等,也就是正反順序相等,所以是回文結(jié)構(gòu),是不是有種恍然大悟的感覺,哈哈。
測試一下:
// test var str = 'Hello, JavaScript' if (isPalindrome(str)) {console.log(str + ' 是回文結(jié)構(gòu)') } else {console.log(str + '不是回文結(jié)構(gòu)') }var str1 = 'A man, a plan, a canal: Panama' if (isPalindrome(str1)) {console.log(str1 + ' 是回文結(jié)構(gòu)') } else {console.log(str1 + '不是回文結(jié)構(gòu)') }node stack.js 得到以下結(jié)果,證明革命成功:
3.2、模擬遞歸
假設(shè)有個需求是求一個數(shù)字的階乘,可能大家很快就能想到以下方法:
// 遞歸問題 function factorial(num) {if (num === 0) {return 1} else {return num * factorial(num - 1)} } console.log(factorial(6))使用棧的話,我們能模擬實(shí)現(xiàn)嗎?
5的階乘為5x4x3x2x1,那么我們把54321都推進(jìn)棧里,然后在出棧時計(jì)算階乘應(yīng)該就可以了吧?試試:
node stack.js 得到以下結(jié)果:
更多JS實(shí)現(xiàn)版數(shù)據(jù)結(jié)構(gòu)與算法請留意本人后續(xù)博客,有錯誤歡迎指出O(∩_∩)O~
總結(jié)
以上是生活随笔為你收集整理的JavaScript数据结构与算法——栈详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 杂志封面语录文字29句
- 下一篇: JavaScript数据结构与算法——队