用js实现链表

单项链表的基本使用

单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始;链表是使用指针进行构造的列表;又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点.

听起来很复杂,直接上图就很好理解了:

在这里插入图片描述
最近在算法题上看到链表就很好奇,毕竟我只听说其他的编程语言上有链表但不知道js怎么去实现,然后通过自己的摸索在大致了解一些,基本是实现了链表。下面是我实现链表的代码:

// 定义节点类
class Node {
  constructor(el) {
    this.el = el
    this.next = null
  }
}
// 定义链表类
class LinkedList {
  constructor() {
    this.size = 0
    this.head = null
  }
  // 末尾添加node
  append(el) {
    let node = new Node(el)
    // 如果链表为空则直接将节点赋值给head
    if (this.size === 0) {
      this.head = node
      this.size++
    } else {
      // 链表不为空将添加带最后一个节点的后面
      let currentNode = this.head
      while (currentNode.next !== null) {
        currentNode = currentNode.next
      }
      currentNode.next = node
      this.size++
    }
  }
  // 根据索引获取node
  get(index) {
    // 如果索引超出范围或着不是数字就会抛出错误
    if ((index < 0) | (index >= this.size) | (typeof index !== 'number')) {
      throw Error('out range or index is not number!')
    }
    // 索引为0 取head的el
    if (index == 0) return this.head
    // 索引不为零 如果取索引为2的就需要调用2次next
    let currentNode = this.head
    while (index) {
      currentNode = currentNode.next
      index--
    }
    return currentNode
  }
  // 向目标节点的后面添加
  insertAfter(el, target) {
    let currentNode = this.head
    // 要插入的节点
    const node = new Node(el)
    // 目标节点
    const targetNode = this.getNode(target)
    // 目标节点的next
    const targetNodeNext = targetNode.next
    // 要插入的节点的next 为目标节点的next
    node.next = targetNodeNext
    // 便利链表 不是目标节点继续next
    while (currentNode !== null && currentNode !== targetNode) {
      currentNode = currentNode.next
    }
    // 在此处currentNode是目标节点
    // 把新的节点覆盖目标节点的next上
    currentNode.next = node
    this.size++
  }
  // 删除指定节点
  remove(el) {
    let currentNode = this.head
    const removeNode = this.getNode(el)
    const removeNodeNext = removeNode.next
    // 如果删除的是第一个节点
    if (currentNode.el == el) {
      this.head = null
      this.size = 0
      return
    }
    // 获取删除节点的前一个节点
    while (currentNode !== null) {
      // 如果当前节点的next时要删除的节点
      if (currentNode.next == removeNode) {
        // 将要删除节点的next接赋值给当前节点的next
        currentNode.next = removeNodeNext
        this.size--
        break
      }
      currentNode = currentNode.next
    }
  }
  // 清空链表
  clear() {
    this.head = null
    this.size = 0
  }
  // 获取指定node
  getNode(el) {
    let currentNode = this.head
    while (currentNode !== null && currentNode.el !== el) {
      currentNode = currentNode.next
    }
    return currentNode
  }
}

效果图:

向末尾添加节点

在这里插入图片描述

查找节点

在这里插入图片描述

在指定节点之后插入新的节点

在这里插入图片描述

删除指定节点
在这里插入图片描述

清空链表
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值