JavaScript数据结构-链表|8月更文挑战

183 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

1. 简介

链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。 每个元素由一个存储元素本身的节点和指向下一个元素的引用(也称指针或链接)组成。

相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然 而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何 位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到 所需的元素。

2.链表的基本结构

链表是通过一个个节点(Node)组成的,每个节点都包含了称为数据域(value)和指针域(next)的基本单元,它也是一种递归的数据结构。它能保持数据之间的逻辑顺序,但存储空间不必按照顺序存储。

2.1链表的基本元素

  • 节点:每个节点有两个部分,数据域(value)存放用户数据;指针域(next)存放指向下一个元素的指针。
  • head:head节点永远指向第一个节点
  • tail: tail永远指向最后一个节点
  • None:链表中最后一个节点的指针域为None值

2.2 链表的方法

  • append(element):向列表尾部添加一个新的项。
  function append (element) {
    let node = new Node(element)
    let head = this.head
    let current
    // 链表为空情况
    if (this.head === null) {
      this.head = node
    } else {
      current = this.head
      while (current.next && current.next !== head) {
        current = current.next
      } 
      current.next = node
    }
    // 保持首尾相连
    node.next = head
    this.length ++
  }
  • insert(position, element):向列表的特定位置插入一个新的项。
  function insert (element, point) {
    if (point >=0 && point <= this.length) {
      let node = new Node(element)
      let current = this.head
      let previous
      let index = 0
      if (point === 0) {
        node.next = current
        while (current.next && current.next !== this.head) {
          current = current.next
        }
        this.head = node
        current.next = this.head
      } else {
        while (index++ < point) {
          previous = current
          current = current.next
        }
        previous.next = node
        // 首尾相连
        node.next = current === null ? head : current
      }
      this.length++
      return true
    } else {
      return false
    }
  }
  • remove(element):从列表中移除一项。
  function remove (element) {
    let index = this.find(element)
    // 删除后返回已删除的节点
    return this.removeAt(index)
  }
  • indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。
  • removeAt(position):从列表的特定位置移除一项。
  function removeAt (point) {
    if (point > -1 && point < this.length) {
      let current = this.head
      let index = 0
      let previous
      if (point === 0) {
        this.head = current.next
        while (current.next && current.next !== this.head) {
          current = current.next
        }
        current.next = this.head
      } else {
        while (index++ < point) {
          previous = current
          current = current.next
        }
        previous.next = current.next
      }
      this.length--
      return current.element
    } else {
      return null
    }
  }
  • isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。
  function isEmpty () {
    return this.length === 0
  }
  • size():返回链表包含的元素个数。与数组的length属性类似。
  function size () {
    return this.length
  }

2.3 链表代码结构

class Node {
  constructor (element) {
    this.element = element
    this.next = null
  }
}
class List {
  constructor () {
    // 初始化链表长度
    this.length = 0
    // 初始化链表第一个节点
    this.head = null
  }

  find (element) {
    let current = this.head
    let index = 0
    if (element == current.element){
        return 0;
    }
    while (current.next && current.next !== this.head) {
      if(current.element === element) {
        return index
      }
      index++
      current = current.next
    }
    if (element == current.element){
        return index;
    }
    return -1
  }

  print () {
    let current = this.head
    let result = ''
    while (current.next && current.next !== this.head) {
      result += current.element + (current.next ? '->' : '')
      current = current.next
    }
    result += current.element
    return result
  }
}

以上是链表学习记录,未完待续。