JavaScript数据结构与算法——队列

43次阅读

共计 1904 个字符,预计需要花费 5 分钟才能阅读完成。

队列和栈非常类似,但是使用了不同的原则,而非后进先出,是先进先出。
1. 队列数据结构
队列遵循 FIFO(先进先出,也称先来先服务)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的的末尾。队列示意图如下:

2. 创建队列
// 创建一个类表示队列
function Queue() {
// 使用数组作为存储队列的数据结构
let items = [];
// 下面声明队列一些可用的方法
// 1.enqueue(elements) 向队尾添加一个或多个项
this.enqueue = function(element) {
items.push(element);
}
// 2.dequeue() 从队列移除元素 FIFO
this.dequeue = function() {
return item.shift();
}
// 3.front() 查看队列头元素
this.front = function() {
return items[0];
}
// 4.isEmpty() size() 检查队列是否为空
this.isEmpty = function() {
return items.length === 0;
}
this.size = function() {
return items.length;
}
// 5. 打印队列元素
this.print = function() {
console.log(items.toString())
}
}
使用 Queue 类
let queue = new Queue();
console.log(queue.isEmpty()); // true
// 添加元素
queue.enqueue(‘june’);
queue.enqueue(‘jack’);

queue.print(); // ‘june,jack’
console.log(queue.size()); // 2
// 删除元素
queue.dequeue();
queue.dequeue();
queue.print(); // ”
3. 优先队列
实现一个有限队列,有两种选择:设置优先级,然后在正确的位置添加元素;或者用入列操作添加元素,然后按照他们的优先级移除他们。
function PriorityQueue() {
let items = [];
// 设置添加元素的类
function QueueElement(element, priority) {
this.element = element;
this.priority = priority;
}
// 优先级添加
this.enqueue = function(element, priority) {
let queueElement = new QueueElement(element, priority);

let added = false;
// 遍原队列中的元素,如果新添加元素的优先级的值(优先级大,priority 值小)小于当前遍历原始的优先级的值(即新添加元素优先级大于当前遍历元素的优先级),则在其前面添加新的元素
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].element}-${items[i].priority}`)
}
}
// 其他方法和默认的 Queue 实现方式相同
}
4. 队列的应用——击鼓传花????(循环队列)
// nameList- 参与的人 num- 每轮传???? 次数
function hotPotato(nameList, num) {
let queue = new Queue();
// 初始化队列
for(let i=0; i<nameList.length; i++) {
queue.enqueue(nameList);
}
//
let eliminated = ”;
// 进行循环队列的入队和出队
while(queue.size() > 1) {
for(let i=0; i<num; i++) {
queue.enqueue(queue.dequeue);
}
// 传花停止 - 淘汰队列第一个
eliminated = queue.dequeue();
console.log(eliminated + ‘ 在击鼓传花???? 中被淘汰。’)
}
// 最后一个出队列的为胜者????
return queue.dequeue();
}

正文完
 0

[ JavaScript ] 数据结构与算法 —— 队列

43次阅读

共计 2396 个字符,预计需要花费 6 分钟才能阅读完成。

前言
JavaScript 是当下最流行的编程语言之一,它可以做很多事情:

数据可视化(D3.js,Three.js,Chart.js);
移动端应用 (React Native,Weex,AppCan,Flutter,Hybrid App, 小程序);
服务端 (Express.js,Koa2);
桌面应用 (Electron,nw.js);
游戏,VR,AR(LayaAir,Egret,Turbulenz,PlayCanvas);
等等。。。

而且目前大部分编程语言的高级应用都会用到数据结构与算法以及设计模式。
本篇主要有三部分

什么是队列
队列的实现
队列的变种

什么是队列
较官方解释
队列是遵循 FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。
注:出队入队是自己加的,不知道是不是这么叫
个人理解
我看有很多文档都是说队列就像买什么东西排队,我认为这个比喻用在标准队列上不恰当。
我觉得标准队列像是一段管道,每次都只能放一个球进去,上边只用来放球(入队),由于地球引力,球会从下边的口出去(出队)。

队列:这段可以放球的管道就是队列 元素:管道里的球 队首:在当前管道里的球最早放进去的那个球的位置,同时也是第一个掉出去的球 队尾:在当前管道里的球最后放进去的那个球的位置,同时也是最后一个掉出去的球
队列的实现

添加队列成员
删除队列成员
返回队首的成员
队列是否为空
清空队列
队列长度
返回字符串形式的队列成员

class Queue {
constructor() {
this.count = 0; // 整个队列下一成员的位置
this.lowestCount = 0; // 在第一位的成员位置
this.items = {}; // 用来存放的队列
}

enqueue(element) {
// 添加队列成员 进入队列
}

dequeue() {
// 删除队列成员 离开队列
}

peek() {
// 返回队首的成员
}

isEmpty() {
// 判断队列是否为空
}

clear() {
// 将所有的数据初始化
}

size() {
// 队列长度
}

toString() {
// 返回字符串形式的队列成员
}
}
添加队列成员
enqueue(element) {
this.items[this.count] = element; // 将元素放入队列
this.count++; // 将计数器加一
}
删除队列成员
dequeue() {
if (this.isEmpty()) {// 如果是空
return undefined; // 返回未定义 undefined
}
const result = this.items[this.lowestCount]; // 将队首的成员保存下
delete this.items[this.lowestCount]; // 将队首的成员删除掉 删除对象属性
this.lowestCount++; // 将队列提前一位 指向队首的指针后移一位
return result; // 返回被删除的成员
}
返回队首的成员
peek() {
if (this.isEmpty()) {// 非空才能继续处理
return undefined;
}
return this.items[this.lowestCount];
}
队列是否为空
isEmpty() { // 判断长度是不是 0
return this.size() === 0;
}
清空队列
clear() {
this.count = 0; // 恢复初始值
this.lowestCount = 0; // 恢复初始值
this.items = {}; // 重新赋值空对象
}
队列长度
size() { // 队列长度 等于 整个队列下一成员的位置 减去 在第一位的成员位置
return this.count – this.lowestCount;
}
返回字符串形式的队列成员
toString() {
if (this.isEmpty()) {
return ”;
}
let objString = `${this.items[this.lowestCount]}`;
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString},${this.items[i]}`;
}
return objString;
}
队列的变种
优先队列
类似去医院看病,急诊,会优先一般的门诊
循环队列
类似抢凳子游戏,队列首位相连
优先队列
在添加成员时会判断优先级,
class QueueElement (element, priority){// 队列成员类
this.element = element; // 存放成员
this.priority = priority; // 存放优先级
}

enqueue(element, priority){
let queueElement = new QueueElement(element, priority); // 添加成员
let added = false; // 是否已添加到队列
for (let i = 0; i < this.size(); i++){// 遍历队列
if (queueElement.priority < items[i].priority){// 寻找优先级低的成员,并插入到其之前
// splice start
for(let j = this.size(); j > i; j–){
items[j] = items[j-1];
}
items[i] = queueElement;
// splice end
added = true; // 标识符置为真,表示已经添加
break; // 跳出循环
}
}
if (!added){// 如果没有找到优先级比新添加的成员低的,那么将其添加到队尾
items.push(queueElement);
}
};
循环队列
在操作时每删除一个队列成员就将删除的这个队列成员重新添加到队列中
for (let i = 0; i < number; i++){
queue.enqueue(queue.dequeue());
}

正文完
 0