算法题:链表实现队列

要点

  • 单向链表,同时记录 head 和 tail
  • 从 tail 入队,从 head 出队,否则出队时tail不好定位
  • length 实时记录,不可遍历链表获取
/**
 * @description 链表实现队列
 * @author lsr
 */

interface ILinkListNode {
  value: number
  next: ILinkListNode | null
}

export class Queue {
  private head: ILinkListNode | null = null
  private tail: ILinkListNode | null = null
  private len = 0

  /**
   * 在 tail 入队(尾部)
   * @param value
   */
  add(value: number) {
    const newNode: ILinkListNode = {
      value,
      next: null
    }

    // 处理 head
    if (this.head === null) {
      this.head = newNode
    }

    // 判断 tail 是否有值,有值则入队
    const tailNode = this.tail
    if (tailNode) {
      tailNode.next = newNode
    }

    // 重新设置 tail
    this.tail = newNode

    // 记录 length
    this.len++
  }

  /**
   * 在 head 出队(头部)
   * @returns value | null
   */
  delete(): number | null {
    // 判断 head 是否有值,没有则返回 null
    const headNode = this.head
    // (尾部的 next 为null)
    if (headNode === null) return null
    if (this.len <= 0) return null

    // 取出 value
    const value = headNode.value

    // 重新设置 head
    this.head = headNode.next

    // 记录 length
    this.len--

    return value
  }
  get length(): number {
    // 实时记录 length,不需要遍历获取
    return this.len
  }
}

// 功能测试
// const customQueue = new Queue()
// console.log('length', customQueue.length)
// customQueue.add(100)
// customQueue.add(200)
// customQueue.add(300)
// console.log('length', customQueue.length)
// console.log(customQueue.delete())
// console.log(customQueue.delete())
// console.log(customQueue.delete())
// console.log(customQueue.delete())
// console.log(customQueue.delete())
// console.log('length', customQueue.length)

// 性能测试
const q1 = new Queue()
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') // 6.5009765625 ms
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') // 346.950927734375 ms

单元测试

/**
 * @description 链表实现队列 test
 * @author lsr
 */

import { Queue } from '@/01-algorithm/queue-with-linkList'

describe('链表实现队列', () => {
  it('add add length', () => {
    const queue = new Queue()
    expect(queue.length).toBe(0)
    queue.add(100)
    queue.add(200)
    queue.add(300)
    queue.add(400)
    queue.add(500)
    queue.add(600)
    expect(queue.length).toBe(6)
  })

  it('delete add length', () => {
    const queue = new Queue()
    expect(queue.delete()).toBeNull()
    queue.add(100)
    queue.add(200)
    queue.add(300)
    queue.add(400)
    queue.add(500)
    queue.add(600)
    expect(queue.delete()).toBe(100)
    expect(queue.delete()).toBe(200)
    expect(queue.delete()).toBe(300)
    expect(queue.delete()).toBe(400)
    expect(queue.length).toBe(2)
    expect(queue.delete()).toBe(500)
    expect(queue.length).toBe(1)
    expect(queue.delete()).toBe(600)
    expect(queue.length).toBe(0)
    expect(queue.delete()).toBeNull()
    expect(queue.delete()).toBeNull()
    expect(queue.delete()).toBeNull()
    expect(queue.length).toBe(0)
  })

  it('add add length again', () => {
    const queue = new Queue()
    queue.add(100)
    queue.add(200)
    expect(queue.delete()).toBe(100)
    expect(queue.delete()).toBe(200)
    expect(queue.length).toBe(0)
    expect(queue.delete()).toBeNull()
    queue.add(300)
    queue.add(400)
    expect(queue.length).toBe(2)
    expect(queue.delete()).toBe(300)
    expect(queue.delete()).toBe(400)
    expect(queue.length).toBe(0)
  })
})

性能分析

  • 空间复杂度:都是O(n)
  • add 时间复杂度:链表O(1),数组O(1)
  • delete 时间复杂度:链表O(1),数组O(n)

划重点

  • 链表,链表 vs 数组
  • 数据结构的选择,比算法优化更重要
  • 要有时间复杂度的敏感性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值