javascript 队列(queue)算法与说明

队列的介绍

队列是一种遵从先进先出(FIFO)先来先服务的有序的项,就是喝茶拿号模式(最前的号,最先进去)。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。


队列算法实例

1.我有三个元素John,Jack,Camila,按循序添加三个元素,就会得到下图的一个队列。



2.队列删除。

let queue = new Queue()
queue.enqueue('John')
queue.enqueue('Jack')
queue.enqueue('Camila')//John,Jack,Camila添加完毕队列
queue.dequeue()//删除一个元素 Jack,Camila
queue.dequeue()//删除一个元素 Camila




ES6队列实现代码:

let Queue = (function () {

    const items = new WeakMap();//WeakMap对象是密钥/值对的集合,其中密钥被弱引用。键必须是对象,值可以是任意值。

    class Queue {

        constructor () {
            items.set(this, []);
        }

        enqueue(...element) {//向队列尾部添加一个(或多个)新的项
            let q = items.get(this);
            q.push(...element);
        }

        dequeue() {//移除队列的第一个(排在队列最前面的)项,并返回被移除的元素。
            let q = items.get(this);
            let r = q.shift();
            return r;
        }

        front() {//返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息)
            let q = items.get(this);
            return q[0];
        }

        isEmpty(){//如果队列中不包含任何元素,返回true,否则返回false。
            return items.get(this).length == 0;
        }

        size(){//返回队列包含的元素个数,与数组的length属性类似。
            let q = items.get(this);
            return q.length;
        }

        clear(){//清空队列里面的元素。
            items.set(this, []);
        }

        print(){//打印队列为String到控制台
            console.log(this.toString());
        }

        toString(){//输出队列以String模式。
            return items.get(this).toString();
        }
    }
    return Queue;
})();

let queue = new Queue();//实例化



队列的种类

在计算机科学中,队列在原先的版本中,有几种修改版本分别是优先队列循环队列


优先队列

优先队列,就是元素添加和移除是基于优先级的。就是在原来的排队中在分优先级。现实例子就是医院排队看病,病情严重的优先排在前面进行治疗。

let priorityQueue = new PriorityQueue()
priorityQueue.enqueue('John'2)//添加元素和优先级
priorityQueue.enqueue('Jack'1)
priorityQueue.enqueue('Camila'1)//Jack,Camila,John添加完毕队列




ES6代码实例:

let PriorityQueue = (function () {

    class QueueElement {//优先队列元素包含(元素,优先级)
        constructor(element, priority){
            this.element = element;
            this.priority = priority;
        }
    }

    const items = new WeakMap();

    class PriorityQueue { 

        constructor () {
            items.set(this, []);
        }

        enqueue(element, priority){//主要修改,在新元素添加的时候,放到优先级相同位置,但是先添加到队列的元素,我们同样遵从先进先出的原则。
            let queueElement = new QueueElement(element, priority);

            let q = items.get(this);

            let added = false;
            for (let i=0; i<q.length; i++){
                if (queueElement.priority < q[i].priority){
                    q.splice(i,0,queueElement);
                    added = true;
                    break;
                }
            }
            if (!added){
                q.push(queueElement);
            }

            items.set(this, q);
        };

        dequeue() {
            let q = items.get(this);
            let r = q.shift();
            items.set(this, q);
            return r;
        }

        front() {
            let q = items.get(this);
            return q[0];
        }

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

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

        clear(){
            items.set(this, []);
        }

        print(){
            let q = items.get(this);
            for (let i=0; i<q.length; i++){
                console.log(`${q[i].element}  - ${q[i].priority}`);
            }
        };
    }
    return PriorityQueue;
})();


let priorityQueue = new PriorityQueue();



循环队列-击鼓传花

循环队列。现实例子就是击鼓传花(Hot Potato),在游戏中,孩子们围着圆圈,把花尽快地传递给旁边的人。某一时刻传花停止,这个时候花在谁手里,谁就退出圆圈结束游戏。重复这个过程,直到只剩一个孩子(胜利)。

let names = ['John','Jack','Camila','Ingrid','Carl'];
let winner = hotPotato(names, 7);
console.log(winner+"胜利者"//Camila被淘汰。
//Jack被淘汰。
//Carl被淘汰。
//Ingrid被淘汰。
//John胜利者


ES6循环队列实例:

let Queue = (function () {

    const items = new WeakMap();//WeakMap对象是密钥/值对的集合,其中密钥被弱引用。键必须是对象,值可以是任意值。

    class Queue {

        constructor () {
            items.set(this, []);
        }

        enqueue(...element) {//向队列尾部添加一个(或多个)新的项
            let q = items.get(this);
            q.push(...element);
        }

        dequeue() {//移除队列的第一个(排在队列最前面的)项,并返回被移除的元素。
            let q = items.get(this);
            let r = q.shift();
            return r;
        }

        front() {//返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息)
            let q = items.get(this);
            return q[0];
        }

        isEmpty(){//如果队列中不包含任何元素,返回true,否则返回false。
            return items.get(this).length == 0;
        }

        size(){//返回队列包含的元素个数,与数组的length属性类似。
            let q = items.get(this);
            return q.length;
        }

        clear(){//清空队列里面的元素。
            items.set(this, []);
        }

        print(){//打印队列为String到控制台
            console.log(this.toString());
        }

        toString(){//输出队列以String模式。
            return items.get(this).toString();
        }
    }
    return Queue;
})();


function hotPotato (nameList, num){
    let queue = new Queue();

    for (let i=0; i<nameList.length; i++){
        queue.enqueue(nameList[i]);
    }

    let eliminated = '';
    while (queue.size() > 1){
        for (let i=0; i<num; i++){
            queue.enqueue(queue.dequeue());//从队列开头移除一项,再将其添加到队列末位。
        }
        eliminated = queue.dequeue();//传递次数达到指定的数字,那个人淘汰。
        console.log(eliminated + '被淘汰。');
    }

    return queue.dequeue();
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值