js 實現數據結構 -- 隊列(Queue)


原文:

  在 Javascript 中學習數據結構與算法。

 

概念:

  與棧相反,隊列是一種遵循先進先出 (FIFO / First In First Out) 原則的一組有序的項;隊列在尾部添加新元素,並從頭部移除元素。最新添加的元素必須排在隊列的末尾。在現實中,最常見的例子就是排隊,吃飯排隊、銀行業務排隊、公車的前門上后門下機制...,前面的人優先完成自己的事務,完成之后,下一個人才能繼續。常見的應用形式是視頻網站的緩沖以及打印隊列。

 

基礎隊列:

class Queue {
    constructor(items) {
        this.items = items || [];
    }

    // 入列
    enqueue(ele) {
        this.items.push(ele);
    }

    // 出列
    dequeue() {
        this.items.shift();
    }

    //
    front() {
        return this.items[0];
    }

    clear() {
        this.items = [];
    }
    get size() {
        return this.items.length;
    }

    get isEmpty() {
        return !this.items.length;
    }

    print() {
        console.log(this.items.toString());
    }
}

let queue = new Queue()
console.log(queue.isEmpty) // true

queue.enqueue('John')
queue.enqueue('Jack')
queue.enqueue('Camila')
console.log(queue.size) // 3
console.log(queue.isEmpty) // false
queue.dequeue()
queue.dequeue()
queue.print() // 'Camila'

 

優先隊列:

  如醫院的急診,雖然都有專門的急診科,但是就理解而言嚴重程度高的可以先就診。優先隊列可以根據優先級進行排列。

  實現思路也簡單,普通隊列直接 push 元素,那么優先隊列就是插入包含優先級的對象,插入前先進行優先級驗證,在相應位置插入元素。

  下例實現根據優先級插入數據,出列操作同普通隊列。

class PriorityQueue {
    constructor() {
        this.items = [];
    }

    get isEmpty() {
        return !this.items.length;
    }

    get size() {
        return this.items.length;
    }

    enqueue(ele, priority) {
        let queueEle = { ele, priority };
        if (this.isEmpty) {
            this.items.push(queueEle);
        } else {
            let preIndex = this.items.findIndex(item => queueEle.priority < item.priority);
            if (preIndex > -1) {
                this.items.splice(preIndex, 0, queueEle);
            } else {
                this.items.push(queueEle);
            }
        }
    }

    dequeue() {
        return this.items.shift();
    }

    front() {
        return this.items[0];
    }

    clear() {
        this.items = [];
    }

    print() {
        console.log(this.items)
    }
}

let priorityQueue = new PriorityQueue()
priorityQueue.enqueue('John', 2)
priorityQueue.enqueue('Jack', 1)
priorityQueue.enqueue('Camila', 1)
priorityQueue.enqueue('Surmon', 3)
priorityQueue.enqueue('skyRover', 2)
priorityQueue.enqueue('司馬萌', 1)
priorityQueue.print()

console.log(priorityQueue.isEmpty, priorityQueue.size) // false 6

 

循環隊列:

  循環隊列在概念上就是將隊尾和隊首閉環。

為充分利用向量空間,克服"假溢出"現象的方法是:將向量空間想象為一個首尾相接的圓環,並稱這種向量為循環向量。存儲在其中的隊列稱為循環隊列(Circular Queue)。這種循環隊列可以以單鏈表的方式來在實際編程應用中來實現。

  js 實現的循環隊列:(基於普通隊列)

class Queue {
    constructor(items) {
        this.items = items || [];
    }

    // 入列
    enqueue(ele) {
        this.items.push(ele);
    }

    // 出列
    dequeue() {
        this.items.shift();
    }

    //
    front() {
        return this.items[0];
    }

    clear() {
        this.items = [];
    }
    get size() {
        return this.items.length;
    }

    get isEmpty() {
        return !this.items.length;
    }

    print() {
        console.log(this.items.toString());
    }
}

class LoopQueue extends Queue {
    constructor(items) {
        super(items)
    }

    getIndex(index) {
        let length = this.items.length;
        return index > length ? index % length : index;
    }

    findIndex(index) {
        return !this.isEmpty ? this.items[this.getIndex(index)] : null;
    }
}


const loopQueue = new LoopQueue(['Surmon'])
loopQueue.enqueue('SkyRover')
loopQueue.enqueue('Even')
loopQueue.enqueue('Alice')
console.log(loopQueue.size, loopQueue.isEmpty) // 4 false

console.log(loopQueue.find(26)) // 'Evan'
console.log(loopQueue.find(87651)) // 'Alice'

 


免責聲明!

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



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