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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

一、隊列

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

  上面我們就已經實現了隊列這種數據結構,同樣的,我們是否可以稍微改造一下,讓隊列的實現看起來更加優美一點。

let Queue = (function () {const items = new WeakMap();class Queue {constructor () {
        //強調一下,這里items是WeakMap類型的數據,而WeakMap是鍵值對,有專屬的set和get方法來獲取和設置值,
        //所以這里給this設置了[],即以this為鍵名,[]為值,所以該方法形成的隊列仍舊是對數組的操作items.set(this,[]);}enqueue(element) {let q = items.get(this);//這里的q就相當于是[]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; })()

  其實到這里隊列就基本介紹完了,但是感覺實在有點糊弄人啊。所以就把剩下的內容都在這一篇文章寫完吧。

二、優先隊列 我們說完了隊列,那么我們看看什么是優先隊列。普通的隊列是一種先進先出的數據結構,元素在隊列尾追加,而從隊列頭刪除。在優先隊列中,元素被賦予優先級。當訪問元素時,具有最高優先級的元素最先刪除。優先隊列具有最高級先出 (first in, largest out)的行為特征。就像是我們在窗口買票,機場排隊,正常來說我們都是依照排隊的順序從隊列的最前面開始依次進入,但是有規定老人孩子軍人等優先,那么就賦予了該老人(孩子軍人)插隊的權利。而優先隊列,同樣就是給特定元素賦予插隊(優先級)的權利。我想要入隊,并不一定是直接到尾部。而是根據我設定的優先級來插入隊列。 其實優先隊列在實現上不同的地方是隊列元素的設定和入隊方法的不同(這里其實有兩種實現方式,一個是按照優先級入列,一個是按照優先級出列,這里我們只用第一種方式實現)。下面我們就看看如何實現優先隊列吧。 //聲明Queue類function PriorityQueue() {//聲明并初始化一個用來存放隊列元素的數組。let items = [];//創建一個擁有優先級的元素類function QueueElement(element,priority) {this.element = element;this.priority = priority; } //添加隊列元素 this.enqueue = function (element,priority) { let queueElement = new QueueElement(element,priority); let added = false; //遍歷隊列元素,1的優先級最高,一次類推,如果當前元素優先級大于items[i],那么就把該元素放在items[i]前面。 //splice方法的第二的參數如果為0,那么則把第三個參數添加到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); } }; //移除并返回該隊列元素 this.dequeue = function () { return items.shift(); }; //獲取隊列頭部元素 this.front = function () { return items[0]; }; //判斷隊列元素是否為空 this.isEmpty = function () { return items.length == 0; }; //獲取隊列元素個數 this.size = function () { return items.length; }; //循環打印元素及其優先級“``”是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();

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

其實這個優先隊列的實現并不是很好,比如我不傳第二優先級參數,那么隊列打印的時候該參數就是undefined,而且在不傳參數的時候應該默認為最末優先級。大家可以試著去修改一下代碼,使其看起來更符合實際。 三、循環隊列   除了優先隊列以外還有循環隊列,循環隊列的一個比較容易想象的例子就是擊鼓傳花游戲,游戲規則就不說了大家小時候都玩過,我們看看如何實現擊鼓傳花游戲。 function hotPotato(nameList, num) {const queue = new Queue();//把所有的名單(nameList)依次入列for (let i = 0; i < nameList.length; i ) {queue.enqueue(nameList[i]);}//聲明當前被淘汰的人員名稱let eliminated = '';//如果隊列中的元素大于一個,說明還沒有最后的贏家,如果只剩下一個,就出列該最后贏家while (queue.size() > 1) { //循環當前隊列num次,把隊列頭部的“出列元素”再入列。 for (let i = 0; i < num; i ) { queue.enqueue(queue.dequeue()); } //循環結束后,出列當前隊列的元素,也就是淘汰者。 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))

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

?

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


更多專業前端知識,請上 【猿2048】www.mk2048.com

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。