JS关于单链表的基本操作

//创建一个节点,每个节点具有两个属性,一个是值和一个指针
class Node {
  constructor(value) {
    this.value = value
    this.next = null
  }
}

//创建一个链表,包含三个属性
class LinkedList {
  constructor() {
    this.head = null 
    this.tail = this.head //用于存储链表的最后一个节点tail
    this.length = 0 //用于保存链表长度
  }

  //按顺序添加值,将一个节点添加到链表的末尾
  append(value) {
    const newNode = new Node(value)
    //检查链表是否为空
    if(!this.head) {//链表为null,将新的节点分别赋给head和tail
      //此时head指向null,因此我们创建一个新对象,并将对象分配给head和tail
      this.head = newNode
      this.tail = newNode
      //现在head和tail都指向一个对象
    } else {//链表不为空,将新的节点追加到链表的尾部
      //现在head不指向null,所以我们进入append函数的else的分支
      this.tail.next = newNode//由于head和tail都指向同一个对象,tail的变化都会导致head对象的变化,这是JS中对象的工作方式,在js中,对象都是通过引用传递的,因此head和tail都指向存储对象的相同地址空间
      //上面这行代码相当于   this.head.next = node
      this.tail = newNode
      //执行完上面的代码行之后,this.head.next和this.tail指向同一个对象,因此当我们添加新节点的时候,head对象都会自动更新
    }
    this.length++
  }


  // //append()函数
  // const linkedList1 = new LinkedList()
  // linkedList1.append(2)
  // linkedList1.append(3)
  // linkedList1.append(4)
  // // //执行完三次append之后,linkedList1的结构
  // // // head: {value: 2 , next: {value: 3, next: {value: 4,next: null}}}
  // // // tail : {value: 4, next: null}
  // // // length:3


  

  //prepend(将值添加到链表开头)
  prepend(value) {
    const node = new Node(value)

    node.next = this.head//将新结点的next指向head
    this.head = node//头结点变为node
    this.length++
  }

  getPrevNextNodes(index) {//这个函数可以返回prevNode和nextNode的值,用于下面的insert()函数
    let count = 0
    let prevNode = this.head
    let nextNode = prevNode.next

    while(count < index - 1) {
      prevNode = prevNode.next
      nextNode = prevNode.next
      count++
    }

    return {
      prevNode,
      nextNode
    }
  }



  //在特定索引处添加值
  insert(value,index) {
    if(index >= this.length) {//若是index的值大于或者等于length属性,则将操作移交给append函数
      this.append(value)//在最后面添加值
    }
    const node = new Node(value)
    const {prevNode,nextNode} = this.getPrevNextNodes(index)//这块我所借鉴的博客写的是 thisg.getPrevNextNodes(index),不知是否正确
    prevNode.next = node//将prevNode的next属性指向新节点
    node.next = nextNode//将新节点的next属性指向nextNode

    this.length++
  }



  getNode(index) {//这个函数可以返回prevNode和currentNode的值,用于下面的remove()函数
    let count = 0
    let prevNode = this.head
    let currentNode = prevNode.next


    while(count < index - 1) {
      prevNode = prevNode.next
      currentNode = prevNode.next
    }


    return {
      prevNode,
      currentNode
    }

  }


  //删除特定索引处的元素
  remove(index){
    let {prevNode,crrentNode} = this.getNode(index)
    prevNode.next = crrentNode.next
    this.length--
  }
  


  //反转链表
  reverse() {
    let previousNode = null
    let currentNode = this.head

    while(currentNode !== null) {
      let nextNode = currentNode.next//将nextNode分配给currentNode.next
      currentNode.next = previousNode//将currentNode.next属性指向previousNode
      previousNode = currentNode//将previousNode移动至currentNode
      currentNode = nextNode//将currentNode移动至nextNode
    }

    this.head = previousNode//最后将previousNode值分配给head
  }




  //查找
  lookup(index) {
    let counter = 0
    let currentNode = this.head
    while(counter < index) {
      currentNode = currentNode.next
      counter++
    }
    return currentNode
  }



}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值