栈和队列
栈
栈是一种运算受限的线性表,先进后出。
应用:函数调用栈
例如:A->B->C->D 函数A调用函数B,函数B调用函数C,函数C调用函数D。
A函数开始执行,将函数A压入栈中,然后函数A调用了函数B,将函数B压入栈中,函数B调用函数C,将函数C压入栈中,函数C调用函数D,将函数D压入栈中。
- 函数D执行完后弹出函数栈,
- 函数C执行完后弹出函数栈,
- 函数B执行完后弹出函数栈,
- 函数A执行完后弹出函数栈。
栈结构实现:
class Stack {
constructor() {
//创建栈
this.items = [];
}
//入栈
push(ele) {
return this.items.push(ele);
}
//出栈
pop() {
return this.items.pop();
}
//查看栈顶
peak() {
return this.items[this.items.length - 1];
}
//栈的长度
size() {
return this.items.length;
}
//栈是否为空
isEmpty() {
return this.items.length == 0;
}
}
队列
队列是一种受限的线性结构,符合先进先出规则(FIFO) frist in first out
受限之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作
队列实现:
//队列
class Queue {
constructor() {
this.items = [];
}
//尾部添加元素
enqueue(ele) {
return this.items.push(ele);
}
//头部删除元素
dequeue() {
return this.items.shift();
}
//查看队列头元素
front() {
return this.items[0];
}
//队列长度
size() {
return this.items.length;
}
//队列是否为空
isEmpty() {
return this.items.length == 0;
}
}
击鼓传花游戏规则:几个朋友一起玩一个游戏, 围成一圈, 开始数数, 数到某个数字的人自动淘汰
代码实现:
//队列实现 :击鼓传花
function passGame(nameList, num) {
//创建队列结构
let q = new Queue();
//将所有的人添加到队列当中
for (let i = 0; i < nameList.length; i++) {
q.enqueue(nameList[i]);
}
//开始数数字
//进行多轮,直到只剩下一个人结束游戏
while (q.size() > 1) {
for (let i = 0; i < num - 1; i++) {
//如果小于num,将此元素再从队列尾部入队
q.enqueue(q.dequeue());
}
//数到num的人,移除队列,被淘汰
q.dequeue();
}
//返回获胜的人
console.log(q.items);
console.log(q.size());
console.log(q.front());
// return q.front();
}
优先级队列
优先级队列不会向普通队列一样直接在队列的尾部添加元素,而是通过比较优先级类添加元素到适当的位置。
应用实例为线程队列,每一个线程都有优先级,优先级高的线程会被计算机优先执行。
实现优先级队列:
//封装优先级队列
class priorityQueue {
constructor() {
this.items = [];
}
//传入值和优先级
enQueue(element, priority) {
//创建一个对象,用于保存值和优先级
let queueElement = {element: element, priority: priority};
//判断队列是否为空
if (this.items.length == 0) {
this.items.push(queueElement);
} else {
//定义done,用于判断是否插入到队列中去了
let done = false;
//如果不为空,遍历队列中的元素,比较优先级,然后插入到合适的位置
for (let i = 0; i < this.items.length; i++) {
if (queueElement.priority < this.items[i].priority) {
this.items.splice(i, 0, queueElement);
done = true;
break;
}
}
//如果没有插入队列
if (!done) {
this.items.push(queueElement);
}
}
}
//头部删除元素
dequeue() {
return this.items.shift();
}
//查看队列头元素
front() {
return this.items[0];
}
//队列长度
size() {
return this.items.length;
}
//队列是否为空
isEmpty() {
return this.items.length == 0;
}
toString() {
let resultString = "";
for (let i = 0; i < this.items.length; i++) {
resultString +=
this.items[i].element + "-" + this.items[i].priority + ";";
}
return resultString;
}
}
let q = new priorityQueue();
q.enQueue("a", 10);
q.enQueue("b", 1);
q.enQueue("c", 6);
q.enQueue("f", 13);
q.enQueue("d", 19);
console.log(q.toString());