3.1:Queue概念
- 队列是一种 列表,不同的是队列只能在队尾插入元素,在队首删除元素。
- 队列是一种先进先出的数据结构。( First-In-First-Out )
- 队列主要的两个操作:队尾插入元素,在队首删除元素。
3.2:Queue的方法
enqueue(element)
向队列尾部添加元素
dequeue()
移除队列的第一项,并返回被移除的元素
peek()
返回队列中第一个元素——最先被添加的
isEmpty()
判断队列是否为空,返回boolean
size()
返回队列包含的元素个数
clear()
清空队列
3.3:Queue的实现
-
创建队列
两本书籍分别采用数组和对象来构造Queue;在前端的实际开发中多数操作对象,在动态渲染数据时经常要定义一些flag来控制一些值的变化,所以将选择 对象来实现Queue;同时对象在获取元素时比数组更高效
class Queue {
constructor() {
dataStore = {}; //使用对象实现队列
count = 0; //控制队列的大小
lowestCount = 0; //追踪第一个元素
};
};
-
enqueue(element) 向队列尾部添加元素
与栈的添加元素方式一样,把count变量作为items对象中的键,对应的元素作为它的值。将元素加入队列后,再将count值加1
enqueue(element) {
this.dataStore[this.count] = element;
this.count ++;
}
-
dequeue() 移除队首元素
判断队列是否为空,为空则返回undefined,不为空继续操作
使用lowestCount找到队首元素,并保存在result变量中
使用delete关键字删除队首元素
删除队首元素后,将lowestCount指向下一个位置
返回保存的队首元素result
dequeue() {
if (this.isEmpty()) {
return undefined;
};
const result = this.dataStore[this.lowestCount];
delete this.items[this.lowestCount];
this.lowestCount++;
return result;
}
-
peek() 查看队首元素
先判断队列是否为空,然后根据lowestCount获取队首的元素
peek() {
if (this.isEmpty()) {
return undefined;
};
return this.dataStore[this.lowestCount];
};
-
isEmpty() 判断队列是否为空
计算count和lowestCount之间的差值,为0表示队列没有元素,则返回true
isEmpty() {
return this.count - this.lowestCount === 0;
};
-
size() 返回队列中元素的数量
//学习js书中的解释直观:
假设count属性的值为2, lowestCount的值为0,这表示在队列中有两个元素。然后从队列中移除一个元素,lowestCount的值会变为1,count的值仍然是2.现在队列中只有一个元素了;
实现size方法,只需返回count和lowestCount之间的差值;
size() {
return this.count - this.lowestCount;
}
-
clear() 清空队列
清空队列只需将队列中的属性值重置
clear() {
this.dataStore = {};
this.count = 0;
this.lowestCount = 0;
}
-
toString()
该方法会打印队列元素,队列的第一个索引不一定为0,所以从lowestCount的位置开始迭代队列
toString() {
if (this.isEmpty()) {
return "";
};
let objString = `${this.dataStore[this.lowestCount]}`;
for (let i = this.lowestCount + 1; i < this.count; i++) {
objString = `${objString}, ${this.dataStore[i]}`;
};
return objString;
};
双端队列 —— Deque
-
创建队列
两本书籍分别采用数组和对象来构造Queue;在前端的实际开发中多数操作对象,在动态渲染数据时经常要定义一些flag来控制一些值的变化,所以将选择 对象来实现Queue;同时对象在获取元素时比数组更高效
class Queue {
constructor() {
dataStore = {}; //使用对象实现队列
count = 0; //控制队列的大小
lowestCount = 0; //追踪第一个元素
};
};
Deque的方法
addFront(element)
在Deque队首添加新元素
addBack(element)
在Deque队尾添加新元素
removeFront()
移除Deque队首元素
removeBack()
移除Deque队尾元素
peekFront()
返回Deque队首元素
peekBack()
返回Deque队尾元素
addBack(element)方法与Queue的enqueue(element)一样;
removeFront()方法与Queue的dequeue()一样;
removeBack()方法与Stack的push()方法一样
-
addFront() 队首添加元素
分三种情况考虑:
Deque队列是空的,添加元素的方法与Queue的添加元素的方式一样;
一个元素已经被双端队列的前端移除,也就是说lowestCount属性会大于1,这种情况下需将lowestCount属性减1并将新元素的值放在这个键的 位置上即可。
lowestCount为0的情况下,在队首添加元素需将所有值往后移动一位,空出第一个位置来添加元素
addFront(element) {
//第一种情况:Deque为空
if(this.isEmpty){
this.enqueue(element);
return;
};
//第二种情况:队首元素已经移除过,lowestCount不为0
if(this.lowestCount > 0) {
this.lowestCount --;
this.dataStore[this.lowestCount] = element;
return;
};
//第三种情况:lowestCount为0
if(this.lowestCount == 0) {
for (let i = this.count; i > 0; i--) {
this.dataStore[i] = this.dataStore[i - 1];
};
this.count ++;
this.lowestCount = 0;
this.dataStore[0] = element;
};
};
优先队列 —— Patient
给队列传递一个参数code作为优先级,code值越大表示优先级越高;
基于Queue结构实现;
定义一个存储队列元素的对象
function Partient(name, code) {
this.name = name; //存储数据
this.code = code; //存储code值
}
筛选优先级最高的元素
使用简单的顺序查找方法寻找优先级最高的元素(code值越大,优先级越高)。该方法返回包含一个元素的数组 -—— 从队列中删除的元素。
choiceCode() {
let priority = this.dataStore[0];
for (let i = 1; i < this.dataStore.length; ++i) {
if (this.dataStore[i].code > priority) {
priority = i;
}
}
return this.dataStore.splice(priority, 1);
};
优先级的实现
let x = new Queue();
let y = new Patient("law", 3);
x.enqueue(y);
let z = new Patient("dan", 2);
x.enqueue(z);
let result = x.choiceCode();