js数据结构-链表结构

36 阅读2分钟

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域.

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。

链表的特点

1.0 插入,删除的数据效率高O(1)级别(只需要改变指针指向即可),随机访问效率O(n)级别(需要从链表头到尾查找)

2.0 和数组相比,内存消耗更大,因为每个存储数据的单元,都需要额外的空间存储后续指针。

3.1单链表结构

每个节点只包含一个指针,既后记指针

  class Node {
      constructor(element){
          this.element = element
          this.next = null
      }
  }
  // 关联数据结构
  class linkNode{
        constructor() {
            this.count = 0
            this.header = null
        }
        push(element){ // 添加数据
            let node = new Node(element)
            console.log(node)
            if(this.header == null){
                this.header = node
            }else {
                let current = this.header
                while (current.next != null){
                    current = current.next
                }
                current.next = node
            }
            this.count ++
        }
      // 指定位置删除
      removeAt(index){
          // 必须大于等于 0 并且小于我们的长度吧
          if(index>=0 && index<this.count){
              let current = this.header;// 当前节点
              if(index==0){
                  this.header = this.header.next
              }else{
                  let previous;// 上一个节点
                  for(let i = 0 ;i<index;i++){
                      previous = current
                      current = current.next
                  }
                  previous.next = current.next
              }
              this.count--
              return current
          }
          return
      }

        // 指定位置删除2
      removeAt2(index){
            // 必须大于等于 0 并且小于我们的长度吧
          if(index>=0 && index<this.count){
              let current = this.header
              if(index==0){
                  this.header = this.header.next
              }else{
                  let previous  = this.getNodeAt(index-1)
                  current = previous.next
                  previous.next = current.next
              }
              this.count --
              return current.element
          }
          return
      }

      // 获取某个位置的节点
      getNodeAt(index){
          if(index>=0 && index<this.count){
              let node = this.header;// 当前节点
              for(let i = 0 ;i<index;i++){
                  node = node.next
              }
              return node
          }
          return
      }

      equalFn(a,b){ // 防止传出的数据 是引用类型的
        return JSON.stringify(a) === JSON.stringify(b)
      }

      // 返回索引值
      indexOf(element){
          let node = this.header;// 当前节点
          for(let i = 0 ;i<this.count;i++) {
              console.log(node.element,element,this.equalFn(node.element, element))
              if (this.equalFn(node.element, element)) {
                  return i
              }
              node = node.next
          }
          return -1
      }

      // 根据值删除
      remove(element){
          let index = this.indexOf(element)
          return this.removeAt2(index)
      }
            // 任意位置 插入
      insert(element,index){
            if(index>=0 && index<=this.count){
                const node = new Node(element)
                if(index==0){ // 链头
                    node.next = this.header
                    this.header = node
                }else{
                    const previos = this.getNodeAt(index-1)
                    node.next = previos.next
                    previos.next = node

                }
            this.count++
            }
            return
      }
      // 链表的大小
      size(){
            return this.count
      }
      // 链表是不是空
      isEmpty(){
            return this.size() === 0
      }
      // 返回列头
      getHead(){
            return this.header
      }
      // 清空链表
      clear(){
            this.count = 0
            this.header = null
      }

  }
  let list = new linkNode()
    list.push(100)
    list.push(200)
    list.push(300)
    list.push({a:1})

想要变优秀,顺其自然是不可能的,你需要做很多,花很多时间,忍耐并且坚持。

qdysh.png