1. 程式人生 > >JS資料結構和演算法 --- 佇列

JS資料結構和演算法 --- 佇列

概念:只允許在表的前端(front)進行刪除操作,在表的後端(rear)進行插入操作的一種特殊線性表

核心思想:先進先出

分類:1)迴圈佇列:普通佇列的首尾相接形成圓環,這樣的佇列稱為迴圈佇列(Circular Queue)

           2)優先佇列:普通佇列的元素被賦予了優先順序,具有最高優先順序的元素最先刪除,這樣的佇列稱為優先佇列(Priority Queue)

操作方法:1)enqueue() 入列,即元素插入佇列

                  2)dequeue() 出列,即從佇列刪除元素

                  3)front() 查詢佇列頭

                  4)isEmpty() 判斷佇列是否為空

                  5)size() 佇列大小

應用場景:適用於多工同步進行操作的場景,根據優先權選擇優先順序高的優先處理。

佇列的理解:把佇列比作是一個排隊的過程,機場裡檢票登機的時候,誰先排隊的誰就優先檢票(先進先出),但是有某些人是VIP會員,可以走VIP通道會比大部分人都優先登機(優先佇列)。

例項

1、佇列的操作方法

/* 定義一個佇列類 */
function Queue(){
    /* 一個佇列 */
    let arr = [];
    /* 查詢佇列 */
    this.getQueue = ()=>{
        return arr;
    },
    /* 入列 */       
    this.enqueue = (element)=>{
        arr.push(element);
    },
    /* 出列 */
    this.dequeue = ()=>{
        return arr.shift();
    },
    /* 檢視佇列頭 */
    this.front = ()=>{
        return arr[0]   
    },
    /* 判斷佇列是否為空 */
    this.isEmpty = ()=>{
        return arr.length == 0;
    },
    /* 查詢佇列大小(即陣列長度) */
    this.size = ()=>{
        return arr.length;
    }
    
}

2、迴圈佇列,破解擊鼓傳花的遊戲

/* 
擊鼓傳花的遊戲:
一群人圍城一圈,一朵花從某個人開始順時針依次傳遞,第三次傳遞拿到花者出局,從下一位又重新開始,已舊是第三次傳遞拿到花者出局,遊戲以這規則進行下去,直到只剩下一個人,即為最終勝利者 
*/
/*
迴圈佇列方法解決問題:
用一個數組代表一圈人,第一次傳花把陣列第一項拿出插入到陣列尾,第二次傳花(在第一次基礎上)又把陣列的第一項拿出插入到陣列尾,第三次(在第二次基礎上)刪除第一項(出局),依次進行下去,直到陣列只剩下一項
*/
function PassTheParcel(people){
    let q = new Queue();           // 呼叫佇列的操作方法
    for(item of people){           
        q.enqueue(item);           //元素一個個入棧
    }
    while(q.size()>1){
        for(let i=0; i<2; i++ ){      //第一次和第二次傳花
            q.enqueue(q.dequeue());        //拿出第一項插入尾部
        }
        q.dequeue();        //第三次出局     
    }
    return '最終勝利者' + q.getQueue();
}

3、優先佇列,根據優先順序插入佇列

/* 定義一個優先佇列類 */
function PriorityQueue(){
    // 優先佇列陣列
    let items = [];
    // 定義一個輔助類(用於建立一項具有優先順序的元素)
    function AuxiliaryClass(element,priority){
        this.element = element;         // 元素名稱
        this.priority = priority;       // 優先順序標識
    }
    // 優先佇列元素入列的方法
    this.enqueue = (element,priority)=>{
        let queueItem = new AuxiliaryClass(element,priority);       // 呼叫輔助類建立一個元素
        let added = false;
        for(let i=0,len=items.length; i<len; i++){      
            if(queueItem.priority > items[i].priority){     // 與每一項做比較,若優先順序比較高,則插入其前面,結束比較
                items.splice(i,0,queueItem);
                added = true;
                break;
            }
        }
        if(!added){             // 比佇列的所有項都小,則插入尾部
            items.push(queueItem);
        }
    };
    this.getPriorityQueue = ()=>{
        return items;
    };
}

(完)