链表实现队列
// queue-with-list // 数组是连续存储:push很快,shift很慢 // 链表是非连续存储,add和delete都很快,但是查找慢 // 结论: 链表实现队列更快 // 数据结构的选择,要比算法优化更重要 // 要有时间复杂度的敏感性,比如:length不能遍历查找,要单独存储 interface IListNode { value: number next: IListNode | null } export class MyQueue { private head: IListNode | null = null private tail: IListNode | null = null private len = 0 /** * 入队,在 tail 位置 * @param n number */ add(n: number) { const newNode: IListNode = { value: n, next: null, } // 处理 head if (this.head == null) { this.head = newNode } // 处理 tail const tailNode = this.tail if (tailNode) { tailNode.next = newNode } this.tail = newNode // 记录长度 this.len++ } /** * 出队,在 head 位置 */ delete(): number | null { const headNode = this.head if (headNode == null) return null if (this.len <= 0) return null // 取值 const value = headNode.value // 处理 head this.head = headNode.next // 记录长度 this.len-- return value } get length(): number { // length 要单独存储,不能遍历链表来获取(否则时间复杂度太高 O(n)) return this.len } } // // 功能测试 // const q = new MyQueue() // q.add(100) // q.add(200) // q.add(300) // console.info('length1', q.length) // console.log(q.delete()) // console.info('length2', q.length) // console.log(q.delete()) // console.info('length3', q.length) // console.log(q.delete()) // console.info('length4', q.length) // console.log(q.delete()) // console.info('length5', q.length) // // 性能测试 // const q1 = new MyQueue() // console.time('queue with list') // for (let i = 0; i < 10 * 10000; i++) { // q1.add(i) // } // for (let i = 0; i < 10 * 10000; i++) { // q1.delete() // } // console.timeEnd('queue with list') // 17ms // const q2 = [] // console.time('queue with array') // for (let i = 0; i < 10 * 10000; i++) { // q2.push(i) // 入队 // } // for (let i = 0; i < 10 * 10000; i++) { // q2.shift() // 出队 // } // console.timeEnd('queue with array') // 431ms
单测
/** * @description 链表实现队列 test * */ import { MyQueue } from './queue-with-list' describe('链表实现队列', () => { it('add and length', () => { const q = new MyQueue() expect(q.length).toBe(0) q.add(100) q.add(200) q.add(300) expect(q.length).toBe(3) }) it('delete', () => { const q = new MyQueue() expect(q.delete()).toBeNull() q.add(100) q.add(200) q.add(300) expect(q.delete()).toBe(100) expect(q.delete()).toBe(200) expect(q.delete()).toBe(300) expect(q.delete()).toBeNull() }) })