本文github地址:JavaScript_Everything 大前端知识体系与面试宝典,从前端到后端,全栈工程师,成为六边形战士
队列的使用场景
线性队列
二叉树的层序遍历
队列的实现
基于数组实现
定义接口
//02.js
interface Queue<T>{
enqueue(element:T):void
dequeue():T | undefined
peek():T | undefined
isEmpty():boolean
size():number
}
实现接口
// 01.js
import './02'
class ArrayQueue<T> implements Queue<T>{
private data:T[] = []
enqueue(element:T):void{
this.data.push(element)
}
dequeue():T | undefined{
return this.data.shift()
}
peek():T|undefined{
return this.data[0]
}
isEmpty():boolean{
return this.data.length === 0
}
size():number{
return this.data.length
}
}
export default ArrayQueue
将队列和栈相同的方法再次进行抽取为 List 接口
// 04.ts
interface List<T>{
peek():T|undefined
isEmpty():boolean
size():number
}
队列接口继承 List 接口
// 05.ts
interface ArrayQueue2<T> extends List<T>{
enqueue(element:T):void
dequeue():T | undefined
}
队列常见面试题
实现击鼓传花
给定一个数组arr,给定一个数字n,每数1个数,队列头部的元素就出列,并立即重新入列成为最后尾部元素,每当到n 时,此时数到的元素从数组中移除,并不进行入队操作,直到数组中只剩下一个元素,并最终返回该元素。
// 07.ts
import ArrayQueue from "./01";
function fn(names:string[], num:number){
if(names.length === 0) return -1
const queue = new ArrayQueue<string>();
for(const name of names) queue.enqueue(name);
while(queue.size() > 1){
for(let i=0;i<3;i++){
const name = queue.dequeue();
if(name) queue.enqueue(name)
}
queue.dequeue()
}
return queue.dequeue();
}
const arr = ['a','b','c','d','e'];
const res = fn(arr, 3);
console.log(res)
约瑟夫环问题
0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。
// 08.js
import ArrayQueue from "./01";
function fn(numbers:number, num:number){
const queue = new ArrayQueue<number>();
for (let index = 0; index < numbers; index++) {
queue.enqueue(index);
}
while(queue.size() > 1){
for(let i=1;i<num;i++){
queue.enqueue(queue.dequeue()!);
}
queue.dequeue()
}
return queue.dequeue();
}
console.log(fn(10, 17))