Skip to content
本页目录

双向链表

本篇在单向链表的基础上手动实现JavaScript中没有的数据结构:双向链表

定义节点

首先我们在单向链表节点结构的基础扩展双向链表结构:

JavaScript
class DoublyNode extends ListNode {
  constructor(val) {
    super(val)
    this.prev = null
  }
}

覆写单链表添加节点

JavaScript
class DoublyLinkedList extends LinkedList {
  constructor() {
    super()
    this.tail = null
  }
  // 覆写单链表添加节点
  addAt(val, idx) {
    if (idx >= 0 && idx <= this.len) {
      const node = new DoublyNode(val)
      let cur = this.head
      if (idx === 0) {
        if (this.head == null) {
          this.head = node
          this.tail = node
        } else {
          node.next = cur
          cur.prev = node
          this.head = node
        }
      } else if (idx === this.len) {
        cur = this.tail
        cur.next = node
        node.prev = cur
        this.tail = node
      } else {
        const prev = this.getAt(idx - 1)
        cur = prev.next
        node.next = cur
        cur.prev = node
        node.prev = prev
        prev.next = node
      }
      this.len++
      return true
    }
    return false
  }
}

覆写单链表移除节点

JavaScript
class DoublyLinkedList extends LinkedList {
  // 其它逻辑代码...
  removeAt(idx) {
    if (idx >= 0 && idx < this.len) {
      let cur = this.head
      if (idx === 0) {
        this.head = cur.next
        if (this.len === 1) {
          this.tail = null
        } else {
          this.head.prev = null
        }
      } else if (idx === this.len - 1) {
        cur = this.tail
        this.tail = cur.prev
        this.tail.next = null
      } else {
        prev = this.getAt(idx - 1)
        cur = prev.next
        prev.next = cur.next
        cur.next.prev = prev
      }
      this.len--
      return cur.val
    }
    return undefined
  }
}

完整代码

查看
JavaScript
class DoublyLinkedList extends LinkedList {
  constructor() {
    super()
    this.tail = null
  }
  // 覆写单链表添加节点
  addAt(val, idx) {
    if (idx >= 0 && idx <= this.len) {
      const node = new DoublyNode(val)
      let cur = this.head
      if (idx === 0) {
        if (this.head == null) {
          this.head = node
          this.tail = node
        } else {
          node.next = cur
          cur.prev = node
          this.head = node
        }
      } else if (idx === this.len) {
        cur = this.tail
        cur.next = node
        node.prev = cur
        this.tail = node
      } else {
        const prev = this.getAt(idx - 1)
        cur = prev.next
        node.next = cur
        cur.prev = node
        node.prev = prev
        prev.next = node
      }
      this.len++
      return true
    }
    return false
  }
  removeAt(idx) {
    if (idx >= 0 && idx < this.len) {
      let cur = this.head
      if (idx === 0) {
        this.head = cur.next
        if (this.len === 1) {
          this.tail = null
        } else {
          this.head.prev = null
        }
      } else if (idx === this.len - 1) {
        cur = this.tail
        this.tail = cur.prev
        this.tail.next = null
      } else {
        prev = this.getAt(idx - 1)
        cur = prev.next
        prev.next = cur.next
        cur.next.prev = prev
      }
      this.len--
      return cur.val
    }
    return undefined
  }
}

数据结构应用

leetcode
  1. LRU(虚拟头尾节点)
  2. LRU缓存