【JavaScript数据结构】链表

67 阅读2分钟

链表是计算机科学中的一个基础数据结构,常常用于实现其它更复杂的数据结构如栈、队列等。在JavaScript中,我们可以用对象来表示链表的节点,并通过引用将它们链接在一起。

以下是一个单链表的例子,包括一些常见的操作和详细的注释:

  1. 链表节点的定义:
// 定义链表节点
class ListNode {
  constructor(value) {
    this.value = value;   // 当前节点的值
    this.next = null;    // 指向下一个节点的引用
  }
}
  1. 链表的定义:
class LinkedList {
  constructor() {
    this.head = null;  // 链表的开始
    this.tail = null;  // 链表的结束
    this.length = 0;   // 链表的长度
  }

  // 添加节点到链表末尾
  append(value) {
    let newNode = new ListNode(value);
    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail.next = newNode;
      this.tail = newNode;
    }
    this.length++;
  }

  // 从链表中删除指定值
  remove(value) {
    if (!this.head) return;

    // 如果头节点就是要删除的值
    if (this.head.value === value) {
      this.head = this.head.next;
      this.length--;
      return;
    }

    let current = this.head;
    while (current.next && current.next.value !== value) {
      current = current.next;
    }

    if (current.next) {
      current.next = current.next.next;
      if (!current.next) {
        this.tail = current;
      }
      this.length--;
    }
  }

  // 打印链表
  print() {
    let current = this.head;
    let values = [];
    while (current) {
      values.push(current.value);
      current = current.next;
    }
    console.log(values.join(" -> "));
  }
}
  1. 插入节点:
  // 在链表的指定位置插入一个新的值
  insert(value, index) {
    if (index < 0 || index > this.length) return false; // 检查索引的有效性

    let newNode = new ListNode(value);
    
    if (index === 0) { // 在链表开始位置插入
      newNode.next = this.head;
      this.head = newNode;
    } else {
      let current = this.head;
      let previous = null;
      let currentIndex = 0;
      while (currentIndex < index) {
        previous = current;
        current = current.next;
        currentIndex++;
      }
      newNode.next = current;
      previous.next = newNode;
    }
    this.length++;
    return true;
  }
  1. 查找节点:
  // 在链表中查找一个值
  find(value) {
    let current = this.head;
    while (current) {
      if (current.value === value) {
        return current; // 如果找到,返回节点
      }
      current = current.next;
    }
    return null; // 如果没有找到,返回null
  }
  1. 翻转链表:
  // 翻转链表
  reverse() {
    let current = this.head;
    let prev = null;
    let next = null;
    
    // 交换每个节点的下一个节点的引用方向
    while (current) {
      next = current.next;
      current.next = prev;
      prev = current;
      current = next;
    }
    
    // 更新头节点
    this.head = prev;
  }
  1. 使用示例:
let list = new LinkedList();

list.append(10);
list.append(20);
list.append(30);
list.print();  // 输出: 10 -> 20 -> 30

list.insert(15, 1);
list.print();  // 输出: 10 -> 15 -> 20 -> 30

console.log(list.find(20));  // 输出: ListNode { value: 20, next: ListNode { value: 30, next: null } }

list.reverse();
list.print();  // 输出: 30 -> 20 -> 15 -> 10