【从今天开始学算法】—— 队列

59 阅读1分钟

队列是遵循先进先出(FIFO)原则的一组有序的项,在尾部添加新元素,从顶部移除元素。

创建队列

class Queue {
    constructor() {
        this.count = 0;
        this.lowestCount = 0;
        this.items = {};
    }
}

队列需要包含的方法

  • enqueue(ele(s)) 向队尾添加一个或多个元素
  • dequeue() 移除队列第一项并返回
  • peek() 返回队列第一项
  • isEmpty() 判空
  • szie() 返回元素个数
  • clear() 清空队列

enqueue

enqueue(ele) {
    this.items[this.count] = ele;
    this.count ++;
}

dequeue

dequeue() {
    if(this.isEmpty()) {
        return undefined;
    }
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount ++;
    return result;
}

peek

peek() {
    if(this.isEmpty()) {
        return undefined;
    }
    return this.items[this.lowestCount];
}

isEmpty

isEmpty() {
    return this.count === this.lowestCount;
    // this.size() === 0
}

size

size() {
    return this.count - this.lowestCount; 
}

clear

clear() {
    this.items = {};
    this.count = 0;
    this.lowestCount = 0;
}

完整代码

class Queue {
    constructor() {
        this.count = 0;
        this.lowestCount = 0;
        this.items = {};
    }
    enqueue(ele) {
        this.items[this.count] = ele;
        this.count ++;
    }
    dequeue() {
        if(this.isEmpty()) {
            return undefined;
        }
        const result = this.items[this.lowestCount];
        delete this.items[this.lowestCount];
        this.lowestCount ++;
        return result;
    }
    peek() {
        if(this.isEmpty()) {
            return undefined;
        }
        return this.items[this.lowestCount];
    }
    isEmpty() {
        return this.count === this.lowestCount;
        // this.size() === 0
    }
    size() {
        return this.count - this.lowestCount; 
    }
    clear() {
        this.items = {};
        this.count = 0;
        this.lowestCount = 0;
    }
}

双端队列

双端队列是一种可以同时从队首和队尾添加和移除元素的特殊队列

class Deque {
    constructor() {
        this.count = 0;
        this.lowestCount = 0;
        this.items = {};
    }
    addFront(ele) {
        this.items[this.lowestCount] = ele;
        this.lowestCount--
    }
    addBack(ele) {
        this.items[this.count] = ele;
        this.count ++;
    }
    removeFront() {
        if(this.isEmpty()) {
            return undefined;
        }
        const result = this.items[this.lowestCount];
        delete this.items[this.lowestCount];
        this.lowestCount ++;
        return result;
    }
    removeBack() {
        if(this.isEmpty()) {
            return undefined;
        }
        const result = this.items[this.count];
        delete this.items[this.count];
        this.count --;
        return result;
    }
    peekFront() {
        if(this.isEmpty()) {
            return undefined;
        }
        return this.items[this.lowestCount];
    }
    peekBack() {
        if(this.isEmpty()) {
            return undefined;
        }
        return this.items[this.count];
    }
    isEmpty() {
        return this.count === this.lowestCount;
        // this.size() === 0
    }
    size() {
        return this.count - this.lowestCount; 
    }
    clear() {
        this.items = {};
        this.count = 0;
        this.lowestCount = 0;
    }
}

应用:击鼓传花

const hotPotato(eleList, num) {
    const queue = new Queue();
    const eleMinList = [];
    for(let i = 0; i < eleList.length; i++) {
        queue.enqueue(eleList[i]);
    }
    
    while(queue.size() > 1) {
        for(let i = 0; i < num; i++) {
            queue.enqueue(queue.dequeue());
        }
        eleMinList.push(queue.dequeue());
    }
    
    return {
        elemin: eleMinList,
        winner: queue.dequeue();
    }
}