日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用js来实现那些数据结构06(队列)

發(fā)布時(shí)間:2023/12/2 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用js来实现那些数据结构06(队列) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  其實(shí)隊(duì)列跟棧有很多相似的地方,包括其中的一些方法和使用方式,只是隊(duì)列使用了與棧完全不同的原則,棧是后進(jìn)先出原則,而隊(duì)列是先進(jìn)先出(First In First Out)。

一、隊(duì)列

隊(duì)列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進(jìn)行刪除操作,而在表的后端(rear)進(jìn)行插入操作,和棧一樣,隊(duì)列是一種操作受限制的線性表。進(jìn)行插入操作的端稱為隊(duì)尾,進(jìn)行刪除操作的端稱為隊(duì)頭。隊(duì)列中沒有元素時(shí),稱為空隊(duì)列。 隊(duì)列的數(shù)據(jù)元素又稱為隊(duì)列元素。在隊(duì)列中插入一個(gè)隊(duì)列元素稱為入隊(duì),從隊(duì)列中刪除一個(gè)隊(duì)列元素稱為出隊(duì)。因?yàn)殛?duì)列只允許在一端插入,在另一端刪除,所以只有最早進(jìn)入隊(duì)列的元素才能最先從隊(duì)列中刪除,故隊(duì)列又稱為先進(jìn)先出(FIFO—first in first out)線性表。 我們對(duì)隊(duì)列有了基本的了解,那么我們來看看如何實(shí)現(xiàn)隊(duì)列。其實(shí)跟棧的實(shí)現(xiàn)極為類似,只是入隊(duì)和出隊(duì)的方法稍有不同,那么我們來看看一個(gè)完整的隊(duì)列需要哪些方法: 1、enqueue(element(s)),入隊(duì),向隊(duì)列尾部添加一個(gè)或者多個(gè)元素。 2、dequeue(),出隊(duì),移除隊(duì)列中的第一個(gè)元素,也就是隊(duì)列最前面的元素,并返回該元素。 3、front(),獲取隊(duì)列最前面的元素,返回隊(duì)列中第一個(gè)元素(最先被添加,也是最先被移除的元素)。隊(duì)列并不移除該元素。 4、isEmpty(),判斷隊(duì)列是否不包含任何元素。 5、size(),返回隊(duì)列的元素總數(shù)。 //聲明Queue類function Queue() {//聲明并初始化一個(gè)用來存放隊(duì)列元素的數(shù)組。let items = [];//添加隊(duì)列元素this.enqueue = function (element) {items.push(element)};//移除并返回該隊(duì)列元素this.dequeue = function () {return items.shift(); }; //獲取隊(duì)列頭部元素 this.front = function () { return items[0]; }; //判斷隊(duì)列元素是否為空 this.isEmpty = function () { return items.length == 0; }; //獲取隊(duì)列元素個(gè)數(shù) this.size = function () { return items.length; }; //打印該隊(duì)列 this.print = function () { console.log(items.toString()) }; } const queue = new Queue(); console.log(queue.isEmpty()); // outputs true queue.enqueue('John'); queue.enqueue('Jack'); queue.print(); // John,Jack queue.enqueue('Camila'); queue.print(); // John,Jack,Camila console.log(queue.size()); // outputs 3 console.log(queue.isEmpty()); // outputs false queue.dequeue(); // remove John queue.dequeue(); // remove Jack queue.print(); // Camila

  上面我們就已經(jīng)實(shí)現(xiàn)了隊(duì)列這種數(shù)據(jù)結(jié)構(gòu),同樣的,我們是否可以稍微改造一下,讓隊(duì)列的實(shí)現(xiàn)看起來更加優(yōu)美一點(diǎn)。

let Queue = (function () {const items = new WeakMap();class Queue {constructor () {
        //強(qiáng)調(diào)一下,這里items是WeakMap類型的數(shù)據(jù),而WeakMap是鍵值對(duì),有專屬的set和get方法來獲取和設(shè)置值,
        //所以這里給this設(shè)置了[],即以this為鍵名,[]為值,所以該方法形成的隊(duì)列仍舊是對(duì)數(shù)組的操作items.set(this,[]);}enqueue(element) {let q = items.get(this);//這里的q就相當(dāng)于是[]q.push(element);}dequeue() {let q = items.get(this); let r = q.shift(); return r; } front() { return items.get(this)[0]; } isEmpty() { return items.get(this).length == 0; } size() { return items.get(this).length; } print() { console.log(items.get(this)); } } return Queue; })()

  其實(shí)到這里隊(duì)列就基本介紹完了,但是感覺實(shí)在有點(diǎn)糊弄人啊。所以就把剩下的內(nèi)容都在這一篇文章寫完吧。

二、優(yōu)先隊(duì)列 我們說完了隊(duì)列,那么我們看看什么是優(yōu)先隊(duì)列。普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭刪除。在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級(jí)。當(dāng)訪問元素時(shí),具有最高優(yōu)先級(jí)的元素最先刪除。優(yōu)先隊(duì)列具有最高級(jí)先出 (first in, largest out)的行為特征。就像是我們?cè)诖翱谫I票,機(jī)場排隊(duì),正常來說我們都是依照排隊(duì)的順序從隊(duì)列的最前面開始依次進(jìn)入,但是有規(guī)定老人孩子軍人等優(yōu)先,那么就賦予了該老人(孩子軍人)插隊(duì)的權(quán)利。而優(yōu)先隊(duì)列,同樣就是給特定元素賦予插隊(duì)(優(yōu)先級(jí))的權(quán)利。我想要入隊(duì),并不一定是直接到尾部。而是根據(jù)我設(shè)定的優(yōu)先級(jí)來插入隊(duì)列。 其實(shí)優(yōu)先隊(duì)列在實(shí)現(xiàn)上不同的地方是隊(duì)列元素的設(shè)定和入隊(duì)方法的不同(這里其實(shí)有兩種實(shí)現(xiàn)方式,一個(gè)是按照優(yōu)先級(jí)入列,一個(gè)是按照優(yōu)先級(jí)出列,這里我們只用第一種方式實(shí)現(xiàn))。下面我們就看看如何實(shí)現(xiàn)優(yōu)先隊(duì)列吧。 //聲明Queue類function PriorityQueue() {//聲明并初始化一個(gè)用來存放隊(duì)列元素的數(shù)組。let items = [];//創(chuàng)建一個(gè)擁有優(yōu)先級(jí)的元素類function QueueElement(element,priority) {this.element = element;this.priority = priority; } //添加隊(duì)列元素 this.enqueue = function (element,priority) { let queueElement = new QueueElement(element,priority); let added = false; //遍歷隊(duì)列元素,1的優(yōu)先級(jí)最高,一次類推,如果當(dāng)前元素優(yōu)先級(jí)大于items[i],那么就把該元素放在items[i]前面。 //splice方法的第二的參數(shù)如果為0,那么則把第三個(gè)參數(shù)添加到i前面。 for(let i = 0; i < items.length; i ) { if(queueElement.priority < items[i].priority) { items.splice(i,0,queueElement); added = true;break; } } // 通過added判斷是否可以直接把元素入列。 if(!added) { items.push(queueElement); } }; //移除并返回該隊(duì)列元素 this.dequeue = function () { return items.shift(); }; //獲取隊(duì)列頭部元素 this.front = function () { return items[0]; }; //判斷隊(duì)列元素是否為空 this.isEmpty = function () { return items.length == 0; }; //獲取隊(duì)列元素個(gè)數(shù) this.size = function () { return items.length; }; //循環(huán)打印元素及其優(yōu)先級(jí)“``”是ES6的模板字符串 this.print = function () { for(let i = 0; i < items.length; i ) { console.log(`${items[i].element} - ${items[i].priority}`); } }; } const queue = new PriorityQueue(); console.log(queue.isEmpty()); // outputs true queue.enqueue('zaking',2); queue.enqueue('linbo',6); queue.enqueue('queue',5); queue.enqueue('ada',3); queue.enqueue('John',1); queue.enqueue('Jack',2); queue.enqueue('Camila',3); queue.enqueue('zak',3); queue.print();

  主要的更改在于隊(duì)列元素的設(shè)置和enqueue方法,由于需要為每一個(gè)循環(huán)隊(duì)列的元素設(shè)置優(yōu)先級(jí),所以這里稍微更改了一下隊(duì)列的元素,使其帶有兩個(gè)參數(shù)(元素自身和優(yōu)先級(jí)),那么既然要根據(jù)不同的優(yōu)先級(jí)來插入隊(duì)列,所以循環(huán)隊(duì)列的enqueue方法也就需要循環(huán)整個(gè)隊(duì)列去判斷要插入到哪里。

其實(shí)這個(gè)優(yōu)先隊(duì)列的實(shí)現(xiàn)并不是很好,比如我不傳第二優(yōu)先級(jí)參數(shù),那么隊(duì)列打印的時(shí)候該參數(shù)就是undefined,而且在不傳參數(shù)的時(shí)候應(yīng)該默認(rèn)為最末優(yōu)先級(jí)。大家可以試著去修改一下代碼,使其看起來更符合實(shí)際。 三、循環(huán)隊(duì)列   除了優(yōu)先隊(duì)列以外還有循環(huán)隊(duì)列,循環(huán)隊(duì)列的一個(gè)比較容易想象的例子就是擊鼓傳花游戲,游戲規(guī)則就不說了大家小時(shí)候都玩過,我們看看如何實(shí)現(xiàn)擊鼓傳花游戲。 function hotPotato(nameList, num) {const queue = new Queue();//把所有的名單(nameList)依次入列for (let i = 0; i < nameList.length; i ) {queue.enqueue(nameList[i]);}//聲明當(dāng)前被淘汰的人員名稱let eliminated = '';//如果隊(duì)列中的元素大于一個(gè),說明還沒有最后的贏家,如果只剩下一個(gè),就出列該最后贏家while (queue.size() > 1) { //循環(huán)當(dāng)前隊(duì)列num次,把隊(duì)列頭部的“出列元素”再入列。 for (let i = 0; i < num; i ) { queue.enqueue(queue.dequeue()); } //循環(huán)結(jié)束后,出列當(dāng)前隊(duì)列的元素,也就是淘汰者。 eliminated = queue.dequeue(); queue.print(); console.log(eliminated "被淘汰"); } return queue.dequeue(); } let names = ["zak","zaking","james","lili","bole","londo","fali"] console.log(hotPotato(names,7))

  上面的方法,每次循環(huán)都會(huì)依次把頭部元素放入到尾部,就實(shí)現(xiàn)了一個(gè)圈,然后我們以循環(huán)結(jié)束后,隊(duì)列最前端的元素視為淘汰,直到最后只剩下一個(gè)元素,也就真實(shí)的模擬了擊鼓傳花游戲。

?

  最后,由于本人水平有限,能力與大神仍相差甚遠(yuǎn),若有錯(cuò)誤或不明之處,還望大家不吝賜教指正。非常感謝!


更多專業(yè)前端知識(shí),請(qǐng)上 【猿2048】www.mk2048.com

總結(jié)

以上是生活随笔為你收集整理的用js来实现那些数据结构06(队列)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。