📜  链表 - Javascript (1)

📅  最后修改于: 2023-12-03 15:12:32.385000             🧑  作者: Mango

链表 - Javascript

链表是一种线性数据结构,它由节点组成,每个节点包括数据和一个指向下一个节点的指针。链表不需要连续的内存空间,可以动态地分配内存空间,但是访问元素的时间复杂度为O(n)。

实现
定义节点
class ListNode {
  constructor(val, next = null) {
    this.val = val;
    this.next = next;
  }
}
定义链表
class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // 在末尾添加元素
  append(val) {
    const newNode = new ListNode(val);

    if (!this.tail) {
      this.head = newNode;
      this.tail = newNode;
    } else {
      this.tail.next = newNode;
      this.tail = newNode;
    }

    this.length++;
  }

  // 在指定位置插入元素
  insert(position, val) {
    if (position < 0 || position > this.length) {
      return false;
    }

    const newNode = new ListNode(val);
    let current = this.head;
    let prev = null;
    let index = 0;

    if (position === 0) {
      newNode.next = current;
      this.head = newNode;
    } else if (position === this.length) {
      this.tail.next = newNode;
      this.tail = newNode;
    } else {
      while (index < position) {
        prev = current;
        current = current.next;
        index++;
      }
      prev.next = newNode;
      newNode.next = current;
    }

    this.length++;
    return true;
  }

  // 删除指定位置的元素
  removeAt(position) {
    if (position < 0 || position >= this.length) {
      return null;
    }

    let current = this.head;
    let prev = null;
    let index = 0;

    if (position === 0) {
      this.head = current.next;
      if (this.length === 1) {
        this.tail = null;
      }
    } else if (position === this.length - 1) {
      while (index < position) {
        prev = current;
        current = current.next;
        index++;
      }
      prev.next = null;
      this.tail = prev;
    } else {
      while (index < position) {
        prev = current;
        current = current.next;
        index++;
      }
      prev.next = current.next;
    }

    this.length--;
    return current.val;
  }

  // 获取指定位置的元素
  get(position) {
    if (position < 0 || position >= this.length) {
      return null;
    }

    let current = this.head;
    let index = 0;

    while (index < position) {
      current = current.next;
      index++;
    }

    return current.val;
  }

  // 设置指定位置的元素
  set(position, val) {
    if (position < 0 || position >= this.length) {
      return false;
    }

    let current = this.head;
    let index = 0;

    while (index < position) {
      current = current.next;
      index++;
    }

    current.val = val;
    return true;
  }

  // 获取元素在链表中的位置
  indexOf(val) {
    let current = this.head;
    let index = 0;

    while (index < this.length) {
      if (current.val === val) {
        return index;
      }
      current = current.next;
      index++;
    }

    return -1;
  }

  // 链表长度
  size() {
    return this.length;
  }

  // 是否为空链表
  isEmpty() {
    return this.length === 0;
  }

  // 清空链表
  clear() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // 打印链表
  print() {
    let current = this.head;
    let str = "";

    while (current) {
      str += current.val;

      if (current.next) {
        str += " -> ";
      }

      current = current.next;
    }

    console.log(str);
  }
}
示例
const linkedList = new LinkedList();

linkedList.append("A");
linkedList.append("B");
linkedList.append("C");

linkedList.insert(2, "D");

linkedList.removeAt(1);

console.log(linkedList.get(2)); // "D"

linkedList.set(2, "E");

console.log(linkedList.indexOf("E")); // 2

console.log(linkedList.size()); // 3

console.log(linkedList.isEmpty()); // false

linkedList.clear();

console.log(linkedList.isEmpty()); // true