[数据结构与算法]ES6封装的单向链表

162 阅读2分钟

本人小白一枚,记录学习中的笔记,如果有错误的地方,请大家多多指教~

let linked_list = (function () {
  class Node {
    constructor (element) {
      this.element = element
      this.next = null
    }
  }
  
  let head = new WeakMap()
  let length = new WeakMap()

  class LinkedList {
    constructor () {
      head = head.set(this, null)
      length.set(this, 0)
    }
    //获取链表的head
    getHead() {
      return head.get(this)
    }
    //获取链表的长度
    getLength() {
      return length.get(this)
    }
    //在链表后面添加新节点
    append(element) {
      //0.新创建一个节点
      let newNode = new Node(element)
      //1.判断当前的head
      let currentHead = this.getHead()
        //1.1如果是空链表,那就设置head
      if (currentHead === null) {
        head.set(this, newNode)
      } else {
        //1.2如果不是空链表则遍历最后一个节点
        while (currentHead.next) {
          currentHead = currentHead.next
        }
        //1.21将最后一个节点的next指向新节点
        currentHead.next = newNode
      }
      //1.3增加新节点之后,长度要加1
      let len =  this.getLength()
      len++
      length.set(this, len)
    }
    //根据节点内容返回index
    getElementIndexOf(element) {
      let currentHead = this.getHead()
      let index = 0
      //1.1如果还没遍历完
      while (currentHead) {
        //1.2如果是当前节点则返回
        if (currentHead.element == element) {
          return index
        } 
        //1.3寻找下一个节点,index++
        currentHead = currentHead.next
        index ++
      }
      //1.4到这里说明已经遍历完了都没找到,返回-1
      return -1
    }
    //根据index返回节点内容
    getIndexOfElement(index) {
      //1.对传入的参数index进行判断
      //1.1不合法返回false
      if (index < 0 || index >= this.getLength()) {
        return false
      } else {
        let currentHead = this.getHead()
        let i = 0
        //2.遍历
        while (i++ < index) {
          currentHead = currentHead.next
        }
        return currentHead
      }
    }
    //在指定位置插入新元素
    insertAt(index, element) {
      //1.对传入的index进行判断合法性
      if (index < 0 || index >= this.getLength()) {
        return null
      } else {
        let currentHead = this.getHead()
        let newNode = new Node(element)
        let currentIndex = 0
        let prevHead
        //1.1如果index = 0表示插在head
        if (index === 0) {
          newNode.next = currentHead 
          head.set(this, newNode )         
        } else {
          //1.2遍历到index后面的一个节点
          while (currentIndex++ < index) {
            prevHead = currentHead          //注意顺序
            currentHead = currentHead.next  //注意顺序
          } 
          newNode.next = currentHead        //注意顺序
          prevHead.next = newNode           //注意顺序
        }
        //2.增加完元素长度就要加1
        let len = this.getLength()
        len ++
        length.set(this, len)
        return true
      }
    }
    //指定删除index的节点
    removeAt(index) {
      //1.判断传入参数index的合法性
      if (index < 0 || index >= this.getLength) {
        return false
      } else {
      let currentHead = this.getHead()
      //1.1判断删除的是head
       if (index === 0) {
         head.set(this, currentHead.next)
       } else {
       //1.1判断删除的不是head
        let currentIndex = 0, prevHead
        //这里是curentIndex ++
        //currentHead => 要被删除的节点
        while (currentIndex++ < index) {
          prevHead = currentHead
          currentHead = currentHead.next
        }
        prevHead.next = currentHead.next
       }
       //2.删除之后长度减少1
       let len = this.getLength()
       len --
       length.set(this, len)
       //3.返回被删除的元素
       return currentHead
      }
    }
    //删除指定的节点
    removeElement(element) {
      //1.先根据元素找到要删除的元素
      let index = this.getElementIndexOf(element)
      return this.removeAt(index)
    }
    //修改指定index的节点
    updateAt(index, element) {
      //1.判断传入参数index的合法性
      if (index < 0 || index >= this.getLength()) {
        return null;
      } else {
        //2.先根据index找到要修改的节点
        let node = this.getIndexOfElement(index)
        //3.修改节点的数据
        return node.element = element
      }
    }
  }
  return LinkedList
})()

let l = new linked_list()
l.append('第一个')
l.append('第二个')
l.append('第三个')
l.updateAt(0, '第0个')
// l.removeElement('第二个')
// l.insertAt(0, '第1个元素前面的')

// console.log(l.getHead())
// console.log('-----')
// l.insertAt(2, '第1个元素后面的')
console.log(l.getHead())