使用 JavaScript 實現基本隊列、優先隊列和循環隊列


1.基本隊列的實現

基本隊列的方法中,包含了 ①向隊列(尾部)中添加元素(enqueue)、②(從隊列頭部)刪除元素(dequeue)、③查看隊列頭部的元素(front)、④查看隊列是否為空(isEmpty)、⑤查看隊列的長度(size)、⑥查看隊列(print) 等 6 個方法

代碼如下:

    function Queue() {
        
        //初始化隊列(使用數組實現)
        var items = [];

        //向隊列(尾部)中插入元素
        this.enqueue = function(element) {
            items.push(element);
        }

        //從隊列(頭部)中彈出一個元素,並返回該元素
        this.dequeue = function() {
            return items.shift();
        }

        //查看隊列最前面的元素(數組中索引為0的元素)
        this.front = function() {
            return items[0];
        }

        //查看隊列是否為空,如果為空,返回true;否則返回false
        this.isEmpty = function() {
            return items.length == 0;
        }

        //查看隊列的長度
        this.size = function() {
            return items.length;
        }

        //查看隊列
        this.print = function() {
            //以字符串形勢返回
            return items.toString();
        }
    }

    var queue = new Queue();
    queue.enqueue('hello');
    queue.enqueue('world');
    queue.enqueue('php');
    queue.enqueue('javascript');
    queue.enqueue('node.js');
    console.log(queue.isEmpty());    // false
    console.log(queue.print());      //hello,world,php,javascript,node.js 
    console.log(queue.size());       //5
    console.log(queue.front());      //hello

    console.log(queue.dequeue());   //hello
    console.log(queue.isEmpty());   //false
    console.log(queue.print());     //world,php,javascript,node.js
    console.log(queue.size());      //4
    console.log(queue.front());     //world

    console.log(queue.dequeue());   //world
    console.log(queue.dequeue());   //php
    console.log(queue.dequeue());   //javascript
    console.log(queue.dequeue());   //node.js
    console.log(queue.isEmpty());   //true
    console.log(queue.print());     //(空字符串)
    console.log(queue.size());      //0
    console.log(queue.front());     // undefined

 

 

2.優先隊列的實現

在優先隊列中,元素的添加或者刪除是基於優先級的。實現優先隊列有兩種方式:①優先添加,正常出列;②正常添加,優先出列

優先添加,正常出列的(最小優先隊列)例子(這個例子在實現隊列的基礎上,把添加進隊列的元素從普通數據改為對象(數組)類型該對象包含需要添加進隊列的元素的值和優先級):

    function PriorityQueue() {
        
        var items = [];

        //需要插入隊列的元素(該元素為對象,包括值和優先級)
        function QueueElement(element, priority) {
            this.element = element;
            this.priority = priority;
        }

        //插入元素到隊列中的方法
        this.enqueue = function (element, priority) {
            //需要插入隊列的元素
            var queueElement = new QueueElement(element, priority);

            if(this.isEmpty()) {
                //當隊列為空時,直接往隊列中添加元素
                items.push(queueElement);
            }else{
                //當隊列不為空時,遍歷隊列中的元素,當需要添加的元素的優先級小於(隊列中)當前元素的優先級,就把該元素插入到當前元素之前
                var added = false;
                for(var i = 0; i < items.length; i++){
                    if(queueElement.priority < items[i].priority) {
                        items.splice(i, 0, queueElement);
                        added = true;
                        break;//終止隊列循環
                    }
                }
                //當需要添加的元素的優先級比隊列中任何一個元素的優先級都要高時,把該元素插入到隊列的末尾
                if(!added){
                    items.push(queueElement);
                }
            }
        }

        //查看隊列是否為空,如果為空,返回true;否則返回false
        this.isEmpty = function() {
            return items.length == 0;
        }    

        //查看隊列
        this.print = function() {
            return items;
        }        
    }

    var priorityQueue = new PriorityQueue();
    
    priorityQueue.enqueue('dee', 10);
    priorityQueue.enqueue('Learning', 2);
    priorityQueue.enqueue('JavaScript', 8);
    priorityQueue.enqueue('Algorithms', 20);
    priorityQueue.enqueue('Data Structures', 20);

    console.log(priorityQueue.print());

 

輸出(FireFox下):

 [QueueElement { element="Learning",  priority=2}, QueueElement { element="JavaScript",  priority=8}, QueueElement { element="dee",  priority=10}, QueueElement { element="Algorithms",  priority=20}, QueueElement { element="Data Structures",  priority=20}]

 

 

3.循環隊列

可以使用循環隊列來模擬擊鼓傳花的游戲(約瑟夫環問題):一群孩子圍成一圈,每次傳遞 n 個數,停下來時手里拿花的孩子被淘汰,直到隊伍中只剩下一個孩子,即勝利者。

循環隊列,每次循環的時候(從隊列頭部)彈出一個孩子,再把這個孩子加入到隊列的尾部,循環 n 次,循環停止時彈出隊列頭部的孩子(被淘汰),直到隊列中只剩下一個孩子。

該例需要依據 "1.基本隊列" 的 Queue 類來實現。 

代碼:

    //基本隊列
    function Queue() {
        
        //初始化隊列(使用數組實現)
        var items = [];

        //向隊列(尾部)中插入元素
        this.enqueue = function(element) {
            items.push(element);
        }

        //從隊列(頭部)中彈出一個元素,並返回該元素
        this.dequeue = function() {
            return items.shift();
        }

        //查看隊列最前面的元素(數組中索引為0的元素)
        this.front = function() {
            return items[0];
        }

        //查看隊列是否為空,如果為空,返回true;否則返回false
        this.isEmpty = function() {
            return items.length == 0;
        }

        //查看隊列的長度
        this.size = function() {
            return items.length;
        }

        //查看隊列
        this.print = function() {
            //以字符串形勢返回
            return items.toString();
        }
    }

    //循環隊列
    //@param Obj nameList 名單
    //@param Int num 指定的傳遞次數
    function hotPotato(nameList, num) {

        var queue = new Queue();

        //把名單插入隊列
        for(var i = 0; i < nameList.length; i++) {
            queue.enqueue(nameList[i]);
        }

        //淘汰者的名字初始值
        var eliminated = '';

        //當隊列里的人數大於1人時,繼續傳遞
        while(queue.size() > 1) {
            for(var i = 0; i < num; i++) {
                //每次把隊列頭部彈出的隊員再次插入隊列的尾部,行程一個循環隊列
                queue.enqueue(queue.dequeue());
            }
            //當循環停止時,即到了指定的傳遞次數時,彈出隊列頭部的隊員
            eliminated = queue.dequeue();
            console.log(eliminated + '被淘汰');
        }

        //當隊列中只剩下一個隊員時,即是勝利者
        return queue.dequeue();
    }

    var names = ['dee', 'death mask', 'saga', 'mu', 'alexis'];
    var winner = hotPotato(names, 7);
    console.log('勝利者是' + winner);

輸出:

 

我們單位的面試題中有一道題也是一樣的道理:

一群猴子排成一圈,按 1,2,...,n 依次編號。然后從第 1 只開始數,數到第 m 只,把它踢出圈,從它后面再開始數,再數到第 m 只,在把它踢出去...,如此不停的進行下去,直到最后只剩下一只猴子為止,那只猴子就叫做大王。要求編程模擬此過程,輸入 m、n,輸出最后那個大王的編號。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM