JS(ES5,ES6)实现队列数据结构

队列遵循先进先出原则。队列在尾部添加新元素,并从顶部移出元素,最新添加的元素必须排在队列的末尾。
ES5:

function Queue(){
    let items = [];
    // 向队列添加元素
    this.enqueue = function(ele){
        items.push(ele);
    }
    //从队列移出元素
    this.dequeue = function(){
        return items.shift();
    }
    // 查看队头元素
    this.front = function(){
        console.log(items[0]);
        return items[0];
    }
    //获取队列长度
    this.size = function(){
        var len = items.length;
        return len;
    }
    // 检查队列是否为空
    this.isEmpty = function(){
        return items.length == 0;
    }
    // 打印队列
    this.print = function(){
        console.log(items.toString());
    }
}

测试:

var queue = new Queue();
queue.isEmpty();
queue.enqueue(1);
queue.enqueue(2);
queue.isEmpty();
queue.front();           //1
queue.print();           //1,2
queue.dequeue();         
queue.print();           //2

ES6:
我们用一个WeakMap来保存私有属性items,并用闭包来封装Queue类

let Queue = (function(){
    const items = new WeakMap();
    class Queue{
        constructor(){
            items.set(this, []);
        }
        enqueue(ele){
            let q = items.get(this);
            q.push(ele);
        }
        dequeue(){
            let q = items.get(this);
            let res = q.shift();
            console.log('出队',res);
            return res;
        }
        front(){
            let q = items.get(this, []);
            console.log('f:',q[0]);
            return q[0];
        }
        size(){
        	let q = items.get(this, []);
        	let len = q.length;
        	return len;
        }
        isEmpty(){
            let q = items.get(this, []);
            return q.length == 0;
        }
        print(){
            let q = items.get(this, []);
            console.log('print:',q.toString());
        }
    }
    return Queue; 
    
})();

测试:

var queue = new Queue();
queue.isEmpty();
queue.enqueue(1);
queue.enqueue(4);
queue.enqueue(3);
queue.isEmpty();
queue.front();           //1
queue.print();           //1,4,3
queue.dequeue();         //1
queue.print();           //4,3

优先队列
优先队列的元素添加和移出是基于优先级的。
实现一个优先队列,有两种选项:
(1)设置优先级,然后再正确的位置添加元素;
(2)用入列操作添加元素,然后按照优先级移出它们;
下面我将以第一种方法实现:

function PriorityQueue(){
    let items = [];
    function QueueElement(ele, priority){
        this.ele = ele;
        this.priority = priority;
    }
    this.enqueue = function(ele, priority){
        let queueElement = new QueueElement(ele, priority);

        let added = false;
        for(let 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);
        }
    };
    this.print = function(){
        for(let i = 0;i < items.length; i++){
            console.log(`${items[i].priority} - ${items[i].ele}`)
        }
    };
    //其他方法和默认的Queue实现相同
}

测试:

let pQ = new PriorityQueue();
pQ.enqueue('tom',3);
pQ.enqueue('jack',2);
pQ.enqueue('John',2);
pQ.print();      //2-jack   2-John  3-tom

我在这里实现的优先队列称为最小优先队列(将优先级较小的元素放置在队列的最前面),还有最大优先队列(把优先级的值较大的元素放置在队列的最前面)。

循环队列
我们用一个实际例子来理解循环队列(击鼓传花游戏)

function Queue2(nameList, num){
    let queue = new Queue();
    let len = nameList.length;
    for(let i = 0;i < len; 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 + '在击鼓传花游戏中被淘汰!!');
    }
    console.log("胜利者:"+ queue.dequeue());
    return queue.dequeue();
}

测试:

let nameList = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N'];
Queue2(nameList, 5);

结果:
F在击鼓传花游戏中被淘汰!!
L在击鼓传花游戏中被淘汰!!
D在击鼓传花游戏中被淘汰!!
K在击鼓传花游戏中被淘汰!!
E在击鼓传花游戏中被淘汰!!
N在击鼓传花游戏中被淘汰!!
I在击鼓传花游戏中被淘汰!!
G在击鼓传花游戏中被淘汰!!
C在击鼓传花游戏中被淘汰!!
H在击鼓传花游戏中被淘汰!!
M在击鼓传花游戏中被淘汰!!
J在击鼓传花游戏中被淘汰!!
B在击鼓传花游戏中被淘汰!!
胜利者:A

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值