返回

js如何实现单向链表、双向链表?

前端

简介

链表是一种常用的数据结构,由一组节点组成,每个节点包含数据和指向下一个节点的指针。链表可以用于存储各种类型的数据,包括字符串、数字和对象。链表的主要优点是易于插入和删除元素,而且可以在不影响其他元素的情况下访问任何元素。

单向链表

单向链表是一种最简单的链表,每个节点只包含数据和指向下一个节点的指针。单向链表可以用于存储各种类型的数据,包括字符串、数字和对象。

实现

class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // 在链表尾部添加一个元素
  append(data) {
    const node = new Node(data);
    if (this.length === 0) {
      this.head = node;
      this.tail = node;
    } else {
      this.tail.next = node;
      this.tail = node;
    }
    this.length++;
  }

  // 从链表中删除一个元素
  remove(data) {
    if (this.length === 0) {
      return;
    }

    let current = this.head;
    let previous = null;

    while (current) {
      if (current.data === data) {
        if (previous) {
          previous.next = current.next;
        } else {
          this.head = current.next;
        }

        if (current === this.tail) {
          this.tail = previous;
        }

        this.length--;
        break;
      }

      previous = current;
      current = current.next;
    }
  }

  // 在链表中查找一个元素
  find(data) {
    let current = this.head;

    while (current) {
      if (current.data === data) {
        return current;
      }

      current = current.next;
    }

    return null;
  }

  // 打印链表中的所有元素
  print() {
    let current = this.head;

    while (current) {
      console.log(current.data);
      current = current.next;
    }
  }
}

双向链表

双向链表是一种比单向链表更复杂的链表,每个节点包含数据、指向下一个节点的指针和指向前一个节点的指针。双向链表可以用于存储各种类型的数据,包括字符串、数字和对象。双向链表的主要优点是可以在两个方向上遍历链表,而且可以在不影响其他元素的情况下访问任何元素。

实现

class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
    this.prev = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }

  // 在链表尾部添加一个元素
  append(data) {
    const node = new Node(data);
    if (this.length === 0) {
      this.head = node;
      this.tail = node;
    } else {
      this.tail.next = node;
      node.prev = this.tail;
      this.tail = node;
    }
    this.length++;
  }

  // 从链表中删除一个元素
  remove(data) {
    if (this.length === 0) {
      return;
    }

    let current = this.head;
    let previous = null;

    while (current) {
      if (current.data === data) {
        if (previous) {
          previous.next = current.next;
        } else {
          this.head = current.next;
        }

        if (current === this.tail) {
          this.tail = previous;
        }

        if (current.next) {
          current.next.prev = previous;
        }

        this.length--;
        break;
      }

      previous = current;
      current = current.next;
    }
  }

  // 在链表中查找一个元素
  find(data) {
    let current = this.head;

    while (current) {
      if (current.data === data) {
        return current;
      }

      current = current.next;
    }

    return null;
  }

  // 打印链表中的所有元素
  print() {
    let current = this.head;

    while (current) {
      console.log(current.data);
      current = current.next;
    }
  }

  // 从链表中删除所有元素
  clear() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }
}

总结

链表是一种重要的数据结构,在各种应用中都有广泛的使用。单向链表和双向链表都是链表的两种常见类型,每种类型都有其独特的优点和缺点。在选择链表类型时,应根据具体应用的需要进行选择。