摘要:在隊(duì)列的這種數(shù)據(jù)結(jié)構(gòu)里面,新增的元素都在尾部,要移除的元素都在頂部。代碼實(shí)現(xiàn)下面用代碼來(lái)實(shí)現(xiàn)隊(duì)列這個(gè)數(shù)據(jù)結(jié)構(gòu),同樣都采用的語(yǔ)法,我們先定義一個(gè)類來(lái)表示隊(duì)列,然后在這個(gè)類的基礎(chǔ)上定義一下方法來(lái)模擬隊(duì)列的行為。
隊(duì)列和棧非常的類似,但是他們采用了不同的原則,棧采用的是后進(jìn)先出,隊(duì)列正好相反,采用的是先進(jìn)先出的原則。隊(duì)列的定義如下
隊(duì)列是遵循FIFO(先進(jìn)先出)原則的有序集合,新添加的元素保存在隊(duì)列的尾部,要移除的元素保存在隊(duì)列的頂部。在隊(duì)列的這種數(shù)據(jù)結(jié)構(gòu)里面,新增的元素都在尾部,要移除的元素都在頂部。
舉一個(gè)生活中的例子,在我們平時(shí)去吃肯德基吃飯時(shí)肯定要排隊(duì),這條隊(duì)伍就可以看做是一個(gè)隊(duì)列,排在隊(duì)伍前面的就是隊(duì)列的頂部,隊(duì)伍后面的就是隊(duì)列的尾部,后來(lái)的人都要排在隊(duì)伍的后面(隊(duì)列的尾部),這就符合了隊(duì)列先進(jìn)先出的原則了(先排隊(duì)的可以先點(diǎn)餐)。
代碼實(shí)現(xiàn)下面用代碼來(lái)實(shí)現(xiàn)隊(duì)列這個(gè)數(shù)據(jù)結(jié)構(gòu),同樣都采用ES6的語(yǔ)法,我們先定義一個(gè)類Queue來(lái)表示隊(duì)列,然后在這個(gè)類的基礎(chǔ)上定義一下方法來(lái)模擬隊(duì)列的行為。
class Queue { constructor() { // 定義一個(gè)數(shù)組來(lái)保存隊(duì)列里面的元素 this.items = [] } // 在隊(duì)列尾部添加一個(gè)或者多個(gè)元素 enqueue(element) { } // 移除隊(duì)列頂部的元素,并返回被移除的元素 dequeue() { } // 清空隊(duì)列 remove() { } // 返回隊(duì)列頂部的元素,不對(duì)隊(duì)列本身做修改 front() { } // 判斷隊(duì)列是否為空 isEmpty() { } // 返回隊(duì)列里面元素的個(gè)數(shù) length() { } }
這樣我們就定義好一個(gè)基類了,下面來(lái)分別實(shí)現(xiàn)隊(duì)列的行為方法
enqueue第一個(gè)要實(shí)現(xiàn)的就是enqueue方法,這個(gè)方法接收一個(gè)參數(shù),然后把該參數(shù)插入隊(duì)列的尾部,因?yàn)檫@里我們是用數(shù)組來(lái)存儲(chǔ)隊(duì)列的元素的,所以可以用數(shù)組的push方法來(lái)實(shí)現(xiàn)該操作,代碼如下
enqueue (element) { this.items.push(element) }dequeue
下面接著實(shí)現(xiàn)dequeue方法,這個(gè)方法會(huì)從隊(duì)列里面移除項(xiàng),由于隊(duì)列遵循的是先進(jìn)先出的原則,所以我們要移除的元素就是隊(duì)列頂部的元素,同樣因?yàn)檫@里我們是用數(shù)組來(lái)存儲(chǔ)隊(duì)列的元素的,所以可以用數(shù)組的shift方法來(lái)實(shí)現(xiàn)該操作。代碼如下
dequeue () { return this.items.shift() }remove
接著來(lái)實(shí)現(xiàn)remove方法,改方法會(huì)移除隊(duì)列里面所有的項(xiàng),同理我們把保存隊(duì)列元素的數(shù)組置空就好了,代碼如下
remove () { this.items = [] }front
上面的方法都是對(duì)隊(duì)列本身有修改的,接下來(lái)要實(shí)現(xiàn)的方法front做的是只讀操作,front方法會(huì)返回隊(duì)列頂部的元素但不對(duì)隊(duì)列本身進(jìn)行修改,代碼實(shí)現(xiàn)如下
front () { return this.items[0] }isEmpty
isEmpty方法判斷隊(duì)列是否為空,也就是保存隊(duì)列的數(shù)組的長(zhǎng)度是否等于0,代碼實(shí)現(xiàn)如下
isEmpty () { return this.items.length === 0 }length
最后一個(gè)方法返回隊(duì)列的長(zhǎng)度,同理就是返回保存隊(duì)列元素的數(shù)組的長(zhǎng)度就好了,代碼如下
length () { return this.item.length }
這里和棧一樣添加一個(gè)輔助方法print來(lái)打印棧里面的元素,方便我們觀察調(diào)試,這個(gè)方法和隊(duì)列的行為無(wú)關(guān),只是一個(gè)輔助方法
print(){ this.items.forEach((item, index) => { console.log(`${index+1}:${item}`) }) }
這樣隊(duì)列的方法就全部寫好了,最后完整Queue類的代碼如下
class Queue { constructor() { // 定義一個(gè)數(shù)組來(lái)保存隊(duì)列里面的元素 this.items = [] } // 在隊(duì)列尾部添加一個(gè)或者多個(gè)元素 enqueue (element) { this.items.push(element) } // 移除隊(duì)列頂部的元素,并返回被移除的元素 dequeue() { return this.items.shift() } // 清空隊(duì)列 remove() { this.items = [] } // 返回隊(duì)列頂部的元素,不對(duì)隊(duì)列本身做修改 front() { return this.items[0] } // 判斷隊(duì)列是否為空 isEmpty() { return this.items.length === 0 } // 返回隊(duì)列里面元素的個(gè)數(shù) length() { return this.item.length } print(){ this.items.forEach((item, index) => { console.log(`${index+1}:${item}`) }) } }使用Queue類
要使用這個(gè)類我們得先實(shí)例化它
const queue = new Queue() queue.isEmpty() // true queue.push("我是隊(duì)列的第一個(gè)元素") queue.push("我是隊(duì)列的第二個(gè)元素") queue.print() // 1: 我是隊(duì)列的第一個(gè)元素 2:我是隊(duì)列的第二個(gè)元素 queue.dequeue() // 我是隊(duì)列的第一個(gè)元素 queue.front() // 我是隊(duì)列的第二個(gè)元素 queue.length() // 1 queue.isEmpty() // false queue.remove() // 這時(shí)隊(duì)列里面已經(jīng)沒(méi)有元素了 queue.isEmpty() // true總結(jié)
隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)運(yùn)用的是非常的廣泛的,就比如javaScript的運(yùn)行機(jī)制,我們都知道javaScript是單線程的,是不能同時(shí)執(zhí)行多個(gè)任務(wù),但是單線程就意味著所有任務(wù)需要排隊(duì)。但是在javaScript里面,很多時(shí)候阻止線程運(yùn)行的很慢的是網(wǎng)絡(luò)IO之類,這時(shí)候CPU是空閑的,這樣就會(huì)造成資源的浪費(fèi)。所以javaScript在主線程之外實(shí)現(xiàn)了一個(gè)任務(wù)隊(duì)列,像IO之類比較慢的操作暫時(shí)都會(huì)掛在任務(wù)隊(duì)列上,這樣不會(huì)影響到主線程上任務(wù)的執(zhí)行,等到IO的響應(yīng)回來(lái)后再回到主線程上來(lái)執(zhí)行掛起的任務(wù)。例子就是我們的Ajax請(qǐng)求,定時(shí)器等。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/88724.html
摘要:原文地址學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)一棧和隊(duì)列博主博客地址的個(gè)人博客幾乎所有的編程語(yǔ)言都原生支持?jǐn)?shù)組類型,因?yàn)閿?shù)組是最簡(jiǎn)單的內(nèi)存數(shù)據(jù)結(jié)構(gòu)。他們就是棧和隊(duì)列。我們稱作棧頂,而另一端我們稱作棧底。移除棧頂?shù)脑兀瑫r(shí)返回被移除元素。 前言 只要你不計(jì)較得失,人生還有什么不能想法子克服的。 原文地址:學(xué)習(xí)javascript數(shù)據(jù)結(jié)構(gòu)(一)——棧和隊(duì)列 博主博客地址:Damonare的個(gè)人博客 幾乎所有的編程...
摘要:而函數(shù)調(diào)用結(jié)束返回時(shí),運(yùn)行時(shí)會(huì)將棧頂?shù)恼{(diào)用結(jié)構(gòu)彈出。并發(fā)模型與引擎是單線程的,它的并發(fā)模型基于事件循環(huán)當(dāng)線程中的同步任務(wù)執(zhí)行完,執(zhí)行棧為空時(shí),則從任務(wù)隊(duì)列中取出異步任務(wù)進(jìn)行處理。在當(dāng)前的微任務(wù)沒(méi)有執(zhí)行完成時(shí),是不會(huì)執(zhí)行下一個(gè)宏任務(wù)的。 堆/棧/隊(duì)列 在javascript中,存在調(diào)用棧 (call stack)和內(nèi)存堆(memory heap) ,程序中函數(shù)依次進(jìn)入棧中等待執(zhí)行,若執(zhí)行...
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過(guò)程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...
摘要:是怎么執(zhí)行的一開始先簡(jiǎn)單聊了聊基本的數(shù)據(jù)結(jié)構(gòu),它和我們現(xiàn)在說(shuō)的事件環(huán)有什么關(guān)系么當(dāng)然有,首先要明確的一點(diǎn)是,代碼的執(zhí)行全都在棧里,不論是同步代碼還是異步代碼,這個(gè)一定要清楚。 棧和隊(duì)列 在計(jì)算機(jī)內(nèi)存中存取數(shù)據(jù),基本的數(shù)據(jù)結(jié)構(gòu)分為棧和隊(duì)列。 棧(Stack)是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),注意,有時(shí)候也管棧叫做堆棧,但是堆又是另一種復(fù)雜的數(shù)據(jù)結(jié)構(gòu),它和棧完全是兩碼事。棧的特點(diǎn)是操作只在一端進(jìn)行...
今天我們講講JavaScript隊(duì)列數(shù)據(jù)結(jié)構(gòu)詳解。 什么是隊(duì)列? 隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),隊(duì)列有兩種操作:插入和刪除;入隊(duì)和出隊(duì)。簡(jiǎn)單來(lái)說(shuō)就是允許插入的一端稱為隊(duì)尾、允許刪除的一端稱為隊(duì)頭; 如下圖展示了棧這個(gè)數(shù)據(jù)結(jié)構(gòu): JavaScript中的隊(duì)列 要知道JavaScript中沒(méi)有有關(guān)隊(duì)列的數(shù)據(jù)模型,因此我們需要通過(guò)數(shù)組進(jìn)行模擬,當(dāng)數(shù)組中提供的push()和shift()選...
閱讀 2415·2021-09-01 10:41
閱讀 1440·2019-08-30 14:12
閱讀 507·2019-08-29 12:32
閱讀 2856·2019-08-29 12:25
閱讀 2934·2019-08-28 18:30
閱讀 1704·2019-08-26 11:47
閱讀 973·2019-08-26 10:35
閱讀 2588·2019-08-23 18:06