我对JS队列的学习

什么是队列

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

在具体应用中通常用链表或者数组来实现。

队列示意图

队列的学习

队列的操作其实是和栈是差不多的,但是队列只允许新数据在后端进行添加。

1 创建队列

声明一个类

function Queue() {
    //这里是属性和方法
}

需要一个用于存储队列中的元素的数据结构,这里选择数组。

var items = [];

2 队列的基本操作

  • 添加元素到队列(只能添加到队列的末尾)

this.enqueue = function (element) {
    items.push(element);
}
  • 移除队列的第一项,并返回被移除的元素

this.dequeue = function() {
    return items.shift();
}
  • 获取队列最前面的元素

this.front = function() {
    return items[0];
}
  • 判断队列是否为空

this.isEmpty = function() {
    return items.length == 0;
}
  • 队列的长度

this.size = function() {
    return items.length;
}

队列和栈的区别是dequeue()方法和front()方法,这是因为先进先出和后进先出的原则不同。

使用Queue类

1.初始化类,验证是否为空

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

2.添加到队列,判断长度

queue.enqueue("John");
queue.enqueue("Jack");
queeu.enqueue("Camila");

console.log(queue.size()); //3

3.移除两个元素,判断长度

queue.dequeue(); 
queue.dequeeu(); 

console.log(queue.size()); //1;这时队列只剩下Camila

优先队列

对,这就是特权!比如登机,头等舱商务舱能和经济舱的登机顺序一样??肯定他们的优先级高啊

实现一个优先队列,有两种选项:①设置优先级,然后在正确的位置添加元素。②用入列操作添加元素,然后按照优先级移除它们。

就是登机,你可以让优先级高的先进去候车室,然后登机的时候按顺序理所当然的头等舱的先登机。另一种就是头等舱经济舱什么的进去候车室的时候不按优先级,但是呢,等到登机的时候按照优先级喊人进去。

function PriorityQueue() {
    var items = [];

//创建一个元素包含了元素和优先级
    function QueueElement (element, priority) {
        this.element = element;
        thie.priority = priority;
    };

    this.queue = function(element, priority) {
        var queueElement = new QueueElement(element, priority);

//队列为空,直接添加到队列(因为这时根本不用比较优先级啊)
        if(this.isEmpty()) {
            items.push(queueElement);
        } else {
            var added = false;
            //如果要添加的元素的优先级小于某一位置元素,那么就把要添加的元素放在这一位置元素的前面(这里用了splice方法)
            //优先级数字越小,优先级越高,应该越早处理,所以应该越靠近队列前面
            for(var 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);
            }
        }
    };
}
var priorityQueue = new PriorityQueue();

priorityQueue.enqueue("John", 2);
priorityQueue.enqueue("Jack", 1);
priorityQueue.enqueue("Camila", 1);

得到的队列就是 |Jack(1)|Camila(1)|John(2)|,优先级相同只需要放到同优先级的后面就可以。

这里是最小优先队列,优先值较小的元素被放置在队列最前面。

循环队列

击鼓传花,孩子们围成一个圆圈,把花尽快的传递给旁边的人,某一时刻传花停止,这个时候花在谁手里谁就淘汰。重复这个过程直到只剩下一个孩子。

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

//将所有的名字放入队列
    for(var i = 0; i < nameList.length; i++) {
        queue.enqueue(nameList[i]);
    }

    var eliminated = '';
    //一轮游戏淘汰一个人
    while(queue.size() > 1) {
        //一轮游戏传鼓7次
        for(var i = 0; i < num; i++) {
            //传鼓一次,你把花传给别人,你就安全了(队首的人拿花)
            //从队列开头移除一项放到队尾
            queue.enqueue(queue.dequeue());
        }
        //一轮游戏结束,淘汰手里拿花的那个人,即队首的那个
        eliminated = queue.dequeue();
        console.log(eliminated + "被淘汰");
    }

    //得到最后的队首
    return queue.dequeue();
}

var names = ["John", "Jack", "Camila", "Ingrid", 'Carl'];
var winner = hotPotato(names, 7);
console.log('胜利者' + winner);

结果:
Camila Jack Carl Ingrid依次被淘汰
胜利者:John

下一篇链表。。。。


luckyziv
1.2k 声望52 粉丝

摸索中前进!!