摘要:棧的應(yīng)用前面介紹了那么多棧相關(guān)的知識(shí),最后也是介紹棧的應(yīng)用場(chǎng)景的時(shí)候了,棧的實(shí)際應(yīng)用非常廣泛,例如用來(lái)存儲(chǔ)訪問(wèn)過(guò)的任務(wù)或路徑撤銷的操作。
棧的定義
什么是棧?棧是一種遵循后進(jìn)先出原則的有序集合,新添加的或者待刪除的元素都保存在棧的同一端,稱為棧頂,另一端稱為棧底,在棧里,新元素靠近棧頂,舊元素靠近棧底,用個(gè)圖來(lái)看大概這樣式的:
用一個(gè)更形象的例子來(lái)說(shuō)明:上網(wǎng)的時(shí)候,每點(diǎn)擊一個(gè)超鏈接,瀏覽器都會(huì)打開一個(gè)新的頁(yè)面,并且壓入到一個(gè)訪問(wèn)歷史棧中,你可以不斷的點(diǎn)擊打開新的頁(yè)面,但總是可以通過(guò)回退重新訪問(wèn)以前的頁(yè)面,從瀏覽器的訪問(wèn)歷史棧中彈出歷史網(wǎng)頁(yè)地址,從棧頂彈出,總是最新的最先彈出
首先創(chuàng)建一個(gè)類用來(lái)表示棧,接著聲明一個(gè)數(shù)組用來(lái)保存棧里的元素:
function Stack() { let items = [] // 方法聲明 }
創(chuàng)建好棧之后,需要為棧聲明一些方法,棧一般會(huì)包含以下幾個(gè)方法:
push(): 添加新元素到棧頂
pop(): 移除棧頂?shù)脑?,同時(shí)返回被移除的元素
peek(): 返回棧頂?shù)脑?,不?duì)棧做任何修改
isEmpty(): 如果棧里沒(méi)有任何元素就返回true,否則返回false
clear(): 移除棧里的所有元素
size(): 返回棧里的元素個(gè)數(shù)
具體實(shí)現(xiàn):
function Stack() { let items = [] // 添加元素到棧頂,也就是棧的末尾 this.push = function (element) { items.push(element) } // 棧的后進(jìn)先出原則,從棧頂出棧 this.pop = function () { return items.pop() } // 查看棧頂?shù)脑?,訪問(wèn)數(shù)組最后一個(gè)元素 this.peek = function () { return items[items.length - 1] } // 檢查棧是否為空 this.isEmpty = function () { return items.length == 0 } // 返回棧的長(zhǎng)度,棧的長(zhǎng)度就是數(shù)組的長(zhǎng)度 this.size = function () { return items.length } // 清空棧 this.clear = function () { items = [] } // 打印棧元素 this.print = function () { console.log(items.toString()) } }棧的使用
現(xiàn)在我們來(lái)看如何使用棧:
let stack = new Stack() stack.push(1) stack.push(2) stack.push(3) console.log(stack.peek()) // 3 console.log(stack.isEmpty()) // false console.log(stack.size()) // 3
先向棧中加入三個(gè)元素1,2,3,接下來(lái)用一張圖來(lái)看一下入棧的過(guò)程:
入棧過(guò)程都是在棧頂依次入棧,接著調(diào)用peek方法返回棧頂元素3,isEmpty返回false,size返回棧的長(zhǎng)度3,然后在繼續(xù)調(diào)用pop來(lái)看看出棧的過(guò)程:
stack.pop() stack.print() // 1,2
出棧也是和入棧相同,都是從棧頂開始出棧,保證棧的后入先出原則
上面創(chuàng)建了一個(gè)Stack函數(shù)來(lái)充當(dāng)類,并且在里面聲明了一個(gè)私有變量,但是在es6里面是有類的語(yǔ)法的,可以直接用es6新語(yǔ)法來(lái)聲明,代碼大概是這樣事的:
class Stack { constructor () { this.items = [] } push (element) { this.items.push(element) } pop () { return this.items.pop() } peek () { return this.items[items.length - 1] } isEmpty () { return this.items.length == 0 } size () { return this.items.length } clear () { this.items = [] } print () { console.log(this.items.toString()) } } let stack = new Stack() stack.push(1) console.log(stack.isEmpty()) stack.print()
看起來(lái)似乎不錯(cuò),比之前要簡(jiǎn)單,關(guān)鍵是看起來(lái)更加合理,使用的是類的語(yǔ)法,調(diào)用也沒(méi)有什么問(wèn)題,但是如果這么執(zhí)行呢?
console.log(stack.items)
會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,在stack類外面可以直接訪問(wèn)類里面的屬性,按照設(shè)計(jì)items應(yīng)該是Stack類的私有屬性才對(duì),就像之前Stack函數(shù)里面的私有變量,是不能在外部訪問(wèn)的,如何才能將items變成私有屬性呢?應(yīng)該會(huì)有和我一樣想法的人,使用閉包,在閉包里面里面定義私有屬性,然后再將stack類返回回來(lái),代碼實(shí)現(xiàn)大概是這樣的:
let Stack = (function () { let items = new WeakMap() class Stack { constructor () { items.set(this, []) } push (element) { let s = items.get(this) s.push(element) } pop () { let s = items.get(this) return s.pop() } peek () { let s = items.get(this) return s[s.length - 1] } isEmpty () { let s = items.get(this) return s.length == 0 } size () { let s = items.get(this) return s.length } clear () { let s = items.get(this) s = [] } print () { let s = items.get(this) console.log(s.toString()) } } return Stack })()
可能有人會(huì)問(wèn)為什么這里要把items定義成一個(gè)WeakMap對(duì)象,先簡(jiǎn)單介紹一下WeakMap對(duì)象的用法,WeakMap對(duì)象是一對(duì)鍵/值對(duì)的集合,其鍵必須是對(duì)象,值可以是任意的,定義成WeakMap就是為了將items屬性變成私有屬性,在外部調(diào)用Stack對(duì)象的時(shí)候無(wú)法訪問(wèn)到items屬性。
棧的應(yīng)用前面介紹了那么多棧相關(guān)的知識(shí),最后也是介紹棧的應(yīng)用場(chǎng)景的時(shí)候了,棧的實(shí)際應(yīng)用非常廣泛,例如用來(lái)存儲(chǔ)訪問(wèn)過(guò)的任務(wù)或路徑、撤銷的操作。為了有一個(gè)更直觀的應(yīng)用了解,下面會(huì)介紹如何用來(lái)解決計(jì)算機(jī)中的進(jìn)制轉(zhuǎn)換問(wèn)題,將10進(jìn)制轉(zhuǎn)換為其他進(jìn)制數(shù),可能不少人已經(jīng)忘了如何進(jìn)行進(jìn)制轉(zhuǎn)換了,下面先來(lái)看一個(gè)簡(jiǎn)單的10進(jìn)制轉(zhuǎn)2進(jìn)制的過(guò)程:
上面的圖中展示將一個(gè)10進(jìn)制8轉(zhuǎn)化為2進(jìn)制數(shù)的過(guò)程,接下來(lái)看看用棧是如何實(shí)現(xiàn)的:
function conver(num, radix) { let stack = new Stack() let binaryString = "" let digits = "0123456789ABCDEF" while (num > 0) { stack.push(num % radix) num = parseInt(num / radix) } while (!stack.isEmpty()) { binaryString += digits[stack.pop()] } console.log(binaryString) } conver(8, 2) // 1000總結(jié)
這篇文章主要對(duì)棧做了簡(jiǎn)單介紹,動(dòng)手實(shí)踐了棧的實(shí)現(xiàn),以及用棧實(shí)現(xiàn)了一個(gè)簡(jiǎn)單進(jìn)制轉(zhuǎn)換的功能。如果有錯(cuò)誤或不嚴(yán)謹(jǐn)?shù)牡胤?,歡迎批評(píng)指正,如果喜歡,歡迎點(diǎn)贊。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/108885.html
摘要:我對(duì)棧的學(xué)習(xí)因?yàn)槭莻€(gè)新手,所以都是最簡(jiǎn)單的知識(shí)學(xué)習(xí)梳理。棧是一種遵從后進(jìn)先出原則的有序集合,新添加的或者待刪除的元素都保留在棧的末尾,稱作棧頂,另一端叫做棧底。棧的學(xué)習(xí)棧的創(chuàng)建創(chuàng)建一個(gè)類來(lái)表示棧。對(duì)于棧來(lái)說(shuō)只能用和方法來(lái)進(jìn)行添加和刪除元素。 我對(duì)棧的學(xué)習(xí) 因?yàn)槭莻€(gè)新手,所以都是最簡(jiǎn)單的知識(shí)學(xué)習(xí)梳理。 什么是棧 數(shù)組是計(jì)算機(jī)科學(xué)中最常用的數(shù)據(jù)結(jié)構(gòu),是數(shù)據(jù)元素的集合。有時(shí)候我們需要一種添加...
摘要:全棧開發(fā)是一個(gè)學(xué)習(xí)實(shí)現(xiàn)提高的過(guò)程。解除對(duì)開發(fā)人員的限制所有的職業(yè)都在持續(xù)的進(jìn)化。哪怕是爆炸和擁擠的印度招聘市場(chǎng),全棧工程師在年也非常的搶手。印度的創(chuàng)業(yè)公司已經(jīng)開發(fā)意識(shí)到全棧工程師的重要意義,全棧會(huì)越來(lái)越重要。 在不斷壯大的招聘市場(chǎng)上,最需要的是有非常廣泛技術(shù)棧的人。 前言 敬愛的讀者,大家好。大家經(jīng)常討論的話題是作為一個(gè)軟件工程師是一個(gè)持續(xù)學(xué)習(xí)的過(guò)程。因?yàn)楝F(xiàn)有的趨勢(shì)和技術(shù)在軟件領(lǐng)域會(huì)很...
摘要:全棧開發(fā)是一個(gè)學(xué)習(xí)實(shí)現(xiàn)提高的過(guò)程。解除對(duì)開發(fā)人員的限制所有的職業(yè)都在持續(xù)的進(jìn)化。哪怕是爆炸和擁擠的印度招聘市場(chǎng),全棧工程師在年也非常的搶手。印度的創(chuàng)業(yè)公司已經(jīng)開發(fā)意識(shí)到全棧工程師的重要意義,全棧會(huì)越來(lái)越重要。 在不斷壯大的招聘市場(chǎng)上,最需要的是有非常廣泛技術(shù)棧的人。 前言 敬愛的讀者,大家好。大家經(jīng)常討論的話題是作為一個(gè)軟件工程師是一個(gè)持續(xù)學(xué)習(xí)的過(guò)程。因?yàn)楝F(xiàn)有的趨勢(shì)和技術(shù)在軟件領(lǐng)域會(huì)很...
摘要:全棧開發(fā)是一個(gè)學(xué)習(xí)實(shí)現(xiàn)提高的過(guò)程。解除對(duì)開發(fā)人員的限制所有的職業(yè)都在持續(xù)的進(jìn)化。哪怕是爆炸和擁擠的印度招聘市場(chǎng),全棧工程師在年也非常的搶手。印度的創(chuàng)業(yè)公司已經(jīng)開發(fā)意識(shí)到全棧工程師的重要意義,全棧會(huì)越來(lái)越重要。 在不斷壯大的招聘市場(chǎng)上,最需要的是有非常廣泛技術(shù)棧的人。 前言 敬愛的讀者,大家好。大家經(jīng)常討論的話題是作為一個(gè)軟件工程師是一個(gè)持續(xù)學(xué)習(xí)的過(guò)程。因?yàn)楝F(xiàn)有的趨勢(shì)和技術(shù)在軟件領(lǐng)域會(huì)很...
閱讀 3318·2023-04-26 02:27
閱讀 2198·2021-11-22 14:44
閱讀 4194·2021-10-22 09:54
閱讀 3247·2021-10-14 09:43
閱讀 808·2021-09-23 11:53
閱讀 13131·2021-09-22 15:33
閱讀 2775·2019-08-30 15:54
閱讀 2777·2019-08-30 14:04