队列

队列数据结构

队列是遵循先进先出的一组有序的项。

创建队列

  1. function Queue() {}

首先用数组存储队列中元素的数据结构:

  1. let items = []

向队列添加元素

  1. this.enqueue = function(element) {
  2. items.push(element);
  3. };

从队列移除元素

  1. this.dequeue = function() {
  2. return items.shift();
  3. };

查看队列头元素

  1. this.front = function() {
  2. return items[0]
  3. }

检查队列是否为空

  1. this.isEmpty = function() {
  2. return items.length == 0;
  3. };
  4. this.size = function() {
  5. return items.length
  6. };

打印队列元素

  1. this.print = function() {
  2. console.log(items.toString());
  3. };

用ES6实现的Queue类

用一个WeakMap保存私有属性items,并用闭包封装Queue类。

  1. let Queue2 = (function() {
  2. const items = new WeakMap();
  3. class Queue2 {
  4. constructor() {
  5. items.set(this,[]);
  6. }
  7. enqueue(element) {
  8. let q = items.get(this);
  9. q.push(element);
  10. }
  11. }
  12. return Queue2
  13. })();

优先队列

实现一个优先队列有两种选项:设置优先级,然后在正确的位置添加元素;或者用入列操作添加元素,然后按照优先级移除它们。在这个示例中,我们将会在正确的位置添加元素,因此可以对他们使用默认的出列操作:

  1. function PriorityQueue() {
  2. let items = [];
  3. function QueueElement(element, priority) {
  4. this.element = element;
  5. this.priority = priority;
  6. }
  7. this.enqueue = function(element, priority) {
  8. let queueElement = new QueueElement(element, priority);
  9. let added = false;
  10. for(let i = 0; i<items.length; i++){
  11. if(queueElement.priority < items[i].priority) {
  12. items.splice(i,0,queueElement);
  13. added = true;
  14. break;
  15. }
  16. }
  17. if (!added){
  18. items.push(queueElement);
  19. }
  20. };
  21. this.print = function() {
  22. for(let i = 0; i<items.length; i++) {
  23. console.log(`${items[i].element} -
  24. ${items[i].priority}`);
  25. }
  26. };
  27. //其他方法和默认的Queue实现相同
  28. }

和默认类实现上的区别是,要向PriorityQueue添加元素,需要创建一个特殊的元素,这个元素包含了要添加到队列的元素及其在队列中的优先级。

如果队列为空,可以直接将元素入列。否则就需要比较该元素与其他元素的优先级。当找到一个比要添加的元素的priority值更大(优先级更低)的项时,就把新元素插入到他之前。如果要添加的元素的priority值大于任何已有的元素,把它添加到队列的末尾就行了。

循环队列—击鼓传花

孩子么围成一圈,把花尽快地传递给旁边的人,某一时刻传花停止,这个时候花在谁手里,谁就退出圆圈结束游戏。重复这个过程直到只剩一个人。

  1. function hotPotato(nameList, num) {
  2. let queue = new Queue();
  3. for(let i = 0;i<nameList.length;i++){
  4. queue.enqueue(nameList[i]);
  5. }
  6. let eliminated = '';
  7. while(queue.size() > 1) {
  8. for(let i = 0; i<num; i++) {
  9. queue.enqueue(queue.dequeue());
  10. }
  11. eliminated = queue.dequeue();
  12. console.log(eliminated + '被淘汰');
  13. }
  14. return queue.dequeue();
  15. }
  16. let names = ['A','C','D','E','S'], winner = hotPotato(names,7);
  17. console.log('winner is ' + winner);
  18. D被淘汰
  19. C被淘汰
  20. S被淘汰
  21. E被淘汰
  22. winner is A

先把名字加入队列,给定一个数字然后迭代队列。从队列开头移除一项再将其添加到末尾。一旦传递数字达到给定的数字,拿着花的那人就被淘汰。