队列
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
github 手写,tdd 测试通过
import { Queue, passGame } from "./Queue";
import { expect, assert, describe, it, test } from 'vitest';
const queue = new Queue();
describe('Queue', () => {
it('new', () => {
expect(queue.size()).toBe(0)
})
it('enqueue', () => {
queue.enqueue('top')
expect(queue.size()).toBe(1)
})
it('front', () => {
expect(queue.front()).toBe('top')
})
it('iSEmpty', () => {
expect(queue.isEmpty()).toBe(false)
queue.dequeue()
expect(queue.isEmpty()).toBe(true)
})
it('size', () => {
queue.enqueue('1')
queue.enqueue('2')
expect(queue.size()).toBe(2)
})
it('toString', () => {
expect(queue.toString()).toBe('1 2')
})
})
describe('击鼓传花', () => {
it('passGame', () => {
expect(passGame(['ldq', 'link', 'nb'], 5)).toBe(0)
})
})
export class Queue {
queue: any[] = [];
static enqueue: Function;
static dequeue: Function;
static front: Function;
static size: Function;
static isEmpty: Function;
static toString: Function;
enqueue(value: any) {
this.queue.push(value)
}
dequeue() {
return this.queue.shift()
}
front() {
if (this.isEmpty()) {
return undefined
} else {
return this.queue[0]
}
}
size() {
return this.queue.length
}
isEmpty() {
return this.queue.length == 0
}
toString() {
return this.queue.join(' ')
}
}
// 击鼓传花
export function passGame(nameList: any[], num: number) {
// 创建一个队列
const queue = new Queue()
// 将所有的人加入队列
for (let i = 0; i < nameList.length; i++) {
queue.enqueue(nameList[i])
}
// 开始数数字
while (queue.size() == 1) {
for (let i = 0; i < num; i--) {
queue.enqueue(queue.dequeue())
}
queue.dequeue()
}
return nameList.indexOf(queue.front())
}
优先级对列
优先级对列和普通队列的区别 就是在push 的时候有一些区别,会去判断元素的优先级,然后在合适的地方插入
export class PriorityQueue extends Queue {
constructor(
// 处理判断优先级
private hanlder: Function,
// 处理元素
private getElement: Function,
// 处理输出hanlder
public toStrHanlder: Function
) {
super();
}
enqueue(element: QueueEl): void {
const el = this.getElement(element)
if (this.isEmpty()) {
this.queue.push(el)
} else {
var added = false
for (let i = 0; i < this.queue.length; i++) {
if (this.hanlder(el, this.queue[i])) {
this.queue.splice(i, 0, el)
added = true
break;
}
}
if (!added) {
this.queue.push(el)
}
}
}
toString(): string {
return this.queue.map((m: QueueEl) => this.toStrHanlder(m)).join(' ')
}
}
describe('优先级队列', () => {
it('PriorityQueue', () => {
interface QueueEl {
value: any,
priority: number
}
// 比较函数
const hanlder = function (el: any, el2: any): boolean {
return el.priority < el2.priority
}
// 处理元素
const getElement = function (el: QueueEl): QueueEl {
return {
value: el.value,
priority: el.priority / 10
}
}
// 处理输出hanlder
const toStrHanlder = function (element: QueueEl): string {
return element.value + '-' + element.priority
}
const pq = new PriorityQueue(hanlder, getElement, toStrHanlder)
pq.enqueue({ value: 'link', priority: 50 })
pq.enqueue({ value: 'ldq', priority: 100 })
pq.enqueue({ value: 'nb', priority: 10 })
expect(pq.toString()).toBe('nb-1 link-5 ldq-10')
})
})