JavaScript数据结构03 - 行列

一、定义

前面我们进修了栈的完成,行列和栈异常相似,然则使用了差别的准绳,而非后进先出。

行列是遵照FIFO(First In First Out,先进先出)准绳的一组有序的项。行列在尾部增加新元素,并从顶部移除元素。最新增加的元素必需排在行列的末端。

在计算机科学中,一个最常见的例子就是打印行列。比方说我们要打印五份文档。我们会翻开每一个文档,然后点击打印按钮。每一个文档都邑被发送至打印行列。第一个发送到打印行列的文档会起首被打印,以此类推,直到打印完一切文档。

二、行列的完成

2.1 一般行列

建立一般行列类:

// Queue类
function Queue () {
  this.items = [];

  this.enqueue = enqueue;
  this.dequeue = dequeue;
  this.front = front;
  this.isEmpty = isEmpty;
  this.size = size;
  this.clear = clear;
  this.print = print;
}

行列内里有一些声明的辅佐要领:

  • enqueue(element):向行列尾部增加新项
  • dequeue():移除行列的第一项(即排在行列最前面的项),并返回被移除的元素
  • front():返回行列中第一个元素,行列不做任何更改,和Stack的peek()要领相似
  • isEmpty():假如行列中不包括任何元素,返回true,不然返回false
  • size():返回行列包括的元素个数,与数组的length属性相似
  • print():打印行列中的元素
  • clear():清空全部行列

下面我们来逐一完成这些辅佐要领:

// 向行列尾部增加元素
function enqueue (element) {
  this.items.push(element);
}

// 移除行列的第一个元素,并返回被移除的元素
function dequeue () {
  return this.items.shift();
}

// 返回行列的第一个元素
function front () {
  return this.items[0];
}

// 推断是不是为空行列
function isEmpty () {
  return this.items.length === 0;
}

// 猎取行列的长度
function size () {
  return this.items.length;
}

// 清空行列
function clear () {
  this.items = [];
}

// 打印行列里的元素
function print () {
  console.log(this.items.toString());
}

建立一般行列实例举行测试:

// 建立Queue实例
var queue = new Queue();

console.log(queue.isEmpty());     // true
queue.enqueue("John");            // undefined
queue.enqueue("Jack");            // undefined
queue.enqueue("Camila");          // undefined
queue.print();                    // "John,Jack,Camila"
console.log(queue.size());        // 3
console.log(queue.isEmpty());     // false
queue.dequeue();                  // "John"
queue.dequeue();                  // "Jack"
queue.print();                    // "Camila"
queue.clear();                    // undefined
console.log(queue.size());        // 0

2.2 优先行列

2.2.1 定义

一般行列的增加和移除只依靠于先后递次,先来的先增加,厥后的后增加,然后依据先后递次顺次从行列移除。

然则,另有一种行列叫优先行列,元素的增加和移除是依靠优先级的。

一个实际的例子就是机场登机的递次。头等舱和商务舱搭客的优先级要高于经济舱搭客。再比方火车,老年人、妊妇和带小孩的搭客是享有优先检票权的。

2.2.2 分类

优先行列分为两类:

  1. 最小优先行列
  2. 最大优先行列

最小优先行列是把优先级的值最小的元素被安排到行列的最前面(代表最高的优先级)。比方有四个元素:”John”, “Jack”, “Camila”, “Tom”,他们的优先级值分别为4,3,2,1。

那末最小优先行列排序应该为:“Tom”,”Camila”,”Jack”,”John”

最大优先行列恰好相反,把优先级值最大的元素安排在行列的最前面,以上面的为例,最大优先行列排序应该为:“John”, “Jack”, “Camila”, “Tom”

2.2.2 完成

完成一个优先行列,有两种选项:

  1. 设置优先级,依据优先级准确增加元素,然后和一般行列一样一般移除
  2. 设置优先级,和一般行列一样一般按递次增加,然后依据优先级移除

这里最小优先行列和最大优先行列我都采纳第一种体式格局完成,人人能够尝试一下第二种。

所以我只重写enqueue()要领和print()要领,其他要领和上面的一般行列完全相同。完全代码见我的github

完成最小优先行列

// 定义最小优先行列
function MinPriorityQueue () {
  this.items = [];

  this.enqueue = enqueue;
  this.dequeue = dequeue;
  this.front = front;
  this.isEmpty = isEmpty;
  this.size = size;
  this.clear = clear;
  this.print = print;
}

完成最小优先行列enqueue()要领和print()要领

// 优先行列增加元素,要依据优先级推断在行列中的插进去递次
function enqueue (element, priority) {
  var queueElement = {
    element: element,
    priority: priority
  };

  if (this.isEmpty()) {
    this.items.push(queueElement);
  } else {
    var added = false;

    for (var i = 0; i < this.size(); i++) {
      if (queueElement.priority < this.items[i].priority) {
        this.items.splice(i, 0, queueElement);
        added = true;
        break ;
      }
    }

    if (!added) {
      this.items.push(queueElement);
    }
  }
}

// 打印行列里的元素
function print () {
  var strArr = [];

  strArr = this.items.map(function (item) {
    return `${item.element}->${item.priority}`;
  });

  console.log(strArr.toString());
}

最小优先行列测试:

// 建立最小优先行列minPriorityQueue实例
var minPriorityQueue = new MinPriorityQueue();

console.log(minPriorityQueue.isEmpty());     // true
minPriorityQueue.enqueue("John", 1);         // undefined
minPriorityQueue.enqueue("Jack", 3);         // undefined
minPriorityQueue.enqueue("Camila", 2);       // undefined
minPriorityQueue.enqueue("Tom", 3);          // undefined
minPriorityQueue.print();                    // "John->1,Camila->2,Jack->3,Tom->3"
console.log(minPriorityQueue.size());        // 4
console.log(minPriorityQueue.isEmpty());     // false
minPriorityQueue.dequeue();                  // {element: "John", priority: 1}
minPriorityQueue.dequeue();                  // {element: "Camila", priority: 2}
minPriorityQueue.print();                    // "Jack->3,Tom->3"
minPriorityQueue.clear();                    // undefined
console.log(minPriorityQueue.size());        // 0

完成最大优先行列

最大优先行列只要将优先级的推断改成大于号”>”就能够了:

// 最大优先行列MaxPriorityQueue类
function MaxPriorityQueue () {
  this.items = [];

  this.enqueue = enqueue;
  this.dequeue = dequeue;
  this.front = front;
  this.isEmpty = isEmpty;
  this.size = size;
  this.clear = clear;
  this.print = print;
}

// 优先行列增加元素,要依据优先级推断在行列中的插进去递次
function enqueue (element, priority) {
  var queueElement = {
    element: element,
    priority: priority
  };

  if (this.isEmpty()) {
    this.items.push(queueElement);
  } else {
    var added = false;

    for (var i = 0; i < this.items.length; i++) {
      // 注重,只需要将这里改成大于号就能够了
      if (queueElement.priority > this.items[i].priority) {
        this.items.splice(i, 0, queueElement);
        added = true;
        break ;
      }
    }

    if (!added) {
      this.items.push(queueElement);
    }
  }
}

最大优先行列测试:

// 建立最大优先行列maxPriorityQueue实例
var maxPriorityQueue = new MaxPriorityQueue();

console.log(maxPriorityQueue.isEmpty());     // true
maxPriorityQueue.enqueue("John", 1);         // undefined
maxPriorityQueue.enqueue("Jack", 3);         // undefined
maxPriorityQueue.enqueue("Camila", 2);       // undefined
maxPriorityQueue.enqueue("Tom", 3);          // undefined
maxPriorityQueue.print();                    // "Jack->3,Tom->3,Camila->2,John->1"
console.log(maxPriorityQueue.size());        // 4
console.log(maxPriorityQueue.isEmpty());     // false
maxPriorityQueue.dequeue();                  // {element: "Jack", priority: 3}
maxPriorityQueue.dequeue();                  // {element: "Tom", priority: 3}
maxPriorityQueue.print();                    // "Camila->2,John->1"
maxPriorityQueue.clear();                    // undefined
console.log(maxPriorityQueue.size());        // 0

2.3 轮回行列

另有一种行列完成叫做轮回行列

轮回行列的一个例子就是伐鼓传花游戏(Hot Potato)。在这个游戏中,孩子们围城一个圆圈,伐鼓的时候把花尽快的传递给旁边的人。某一时候伐鼓住手,这时候花在谁的手里,谁就退出圆圈直到游戏完毕。反复这个历程,直到只剩一个孩子(胜者)。

下面我们在一般行列的基础上,完成一个模仿的伐鼓传花游戏:

// 完成伐鼓传花
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) {
    // 轮回num次,队首出来去到队尾
    for (var i = 0; i < num; i++) {
      queue.enqueue(queue.dequeue());
    }
    // 轮回num次事后,移除当前队首的元素
    eliminated = queue.dequeue();
    console.log(`${eliminated}在伐鼓传花中被镌汰!`);
  }

  // 末了只剩一个元素
  return queue.dequeue();
}

// 测试
var nameList = ["John", "Jack", "Camila", "Ingrid", "Carl"];
var winner = hotPotato(nameList, 10);
console.log(`末了的胜利者是:${winner}`);

实行效果为:

// John在伐鼓传花中被镌汰!
// Ingrid在伐鼓传花中被镌汰! 
// Jack在伐鼓传花中被镌汰!
// Camila在伐鼓传花中被镌汰!
// 末了的胜利者是:Carl

三、完毕

本文会同步到我的个人博客,完全代码能够到我的github堆栈检察,假如对你有协助的话迎接点一个Star~~

迎接关注我的民众号

《JavaScript数据结构03 - 行列》

    原文作者:liuxuan
    原文地址: https://segmentfault.com/a/1190000015778119
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞