什么是优先级队列
优先级队列(Queue):优先级队列也是队列的一种,在优先级队列中,元素被赋予了优先级,当访问队列中的元素时,高优先级的元素最先被访问。
优先级队列主要考虑两个问题:
- 队列中的数据不再是单个数据还要包括优先级。
- 添加数据的过程中根据优先级添加到对应的位置。
如下图:
Priority
优先级队列的常见操作
主要的方法继承与队列类,所以常见的方法相同。
- enQueue(data,priority) 在队尾的位置为队列添加一个新的数据
- deQueue() 在队头的位置删除队列的第一个元素
- front() 返回队列的首项
- isEmpty() 判断队列是否为空
- size() 返回队列数据的大小
- toString() 以字符串的形式输出队列中的数据
ES6 实现优先级队列结构
我们可以约定,0 为最高优先级。
- 优先级数据内部类的实现
class QueueElement {
constructor(data, priority) {
// 存放数据
this.data = data;
// 存放优先级
this.priority = priority;
}
}
- 优先级队列的实现
/**
* 优先队列
* 主要考虑两个问题
* 1. 队列中的数据不再是单个数据,还要包括优先级
* 2. 添加元素的过程中根据优先级添加到正确的位置当中
*
* @class PriorityQueue
* @extends {Queue}
*/
class PriorityQueue extends Queue {
constructor() {
super();
}
}
- enQueue(data, priority) 方法的实现
// 重写 Queue 类 的 enQueue 方法
enQueue(data, priority) {
// 创建 优先队列的内部数据类的实例
const queueData = new QueueElement(data, priority);
// 判断优先队列是否为空
if (this.isEmpty()) {
// 如果优先队列为空 则不需要判断优先级直接添加数据
this.queue.push(queueData);
} else {
// 创建变量 标识该数据是否比现有的优先级小
let added = false;
for (let i = 0; i < this.queue.length; i++) {
// 新插入的数据和现有的数据的优先级做比较,priority 越小 优先级 越大
if (queueData.priority < this.queue[i].priority) {
this.queue.splice(i, 0, queueData);
added = true;
break;
}
}
if (!added) {
// 如果遍历完所有元素 没有添加进入队列,则证明优先级小,应该添加到队列的末尾
this.queue.push(queueData);
}
}
}
- deQueue() 方法的实现
// dequeue() 出队,从队列中删除前端元素,返回删除的元素
// 继承 Queue 类的 dequeue()
deQueue() {
return super.deQueue();
}
- front() 方法的实现
// front() 查看队列的前端元素
// 继承 Queue 类的 front()
front() {
return super.front();
}
- isEmpty() 方法的实现
// isEmpty() 查看队列是否为空
// 继承 Queue 类的 isEmpty()
isEmpty() {
return super.isEmpty();
}
- size() 方法的实现
// size() 查看队列中元素的个数
// 继承 Queue 类的 size()
size() {
return super.size();
}
- toString() 方法的实现
// toString() 将队列中元素以字符串形式返回
// 重写 toString()
toString() {
let result = "";
for (let item of this.queue) {
result += item.data + "-" + item.priority + " ";
}
return result;
}
优先级队列的总体代码
// 优先队列内部的数据类
class QueueElement {
constructor(data, priority) {
this.data = data;
this.priority = priority;
}
}
/**
* 优先队列
* 主要考虑两个问题
* 1. 队列中的数据不再是单个数据,还要包括优先级
* 2. 添加元素的过程中根据优先级添加到正确的位置当中
*
* @class PriorityQueue
* @extends {Queue}
*/
class PriorityQueue extends Queue {
constructor() {
super();
}
// 重写 Queue 类 的 enQueue 方法
enQueue(data, priority) {
// 创建 优先队列的内部数据类的实例
const queueData = new QueueElement(data, priority);
// 判断优先队列是否为空
if (this.isEmpty()) {
// 如果优先队列为空 则不需要判断优先级直接添加数据
this.queue.push(queueData);
} else {
// 创建变量 标识该数据是否比现有的优先级小
let added = false;
for (let i = 0; i < this.queue.length; i++) {
// 新插入的数据和现有的数据的优先级做比较,priority 越小 优先级 越大
if (queueData.priority < this.queue[i].priority) {
this.queue.splice(i, 0, queueData);
added = true;
break;
}
}
if (!added) {
// 如果遍历完所有元素 没有添加进入队列,则证明优先级小,应该添加到队列的末尾
this.queue.push(queueData);
}
}
}
// dequeue() 出队,从队列中删除前端元素,返回删除的元素
// 继承 Queue 类的 dequeue()
deQueue() {
return super.deQueue();
}
// front() 查看队列的前端元素
// 继承 Queue 类的 front()
front() {
return super.front();
}
// isEmpty() 查看队列是否为空
// 继承 Queue 类的 isEmpty()
isEmpty() {
return super.isEmpty();
}
// size() 查看队列中元素的个数
// 继承 Queue 类的 size()
size() {
return super.size();
}
// toString() 将队列中元素以字符串形式返回
// 重写 toString()
toString() {
let result = "";
for (let item of this.queue) {
result += item.data + "-" + item.priority + " ";
}
return result;
}
}