JS 手写单向链表

// 定义链表元素类
function Linked_node(val) {
  this.val = val;
  this.next = null;
}

// 定义链表类
function Linked_list() {
  this.length = 0;
  this.head = null;
}


// 给链表类添加方法

// 方法一(通过节点的索引查找对应的节点)
Linked_list.prototype.getNodeByIndex = function (index) {
  // 先判断错误的值(val不是数字,val小于0,val大于链表的长度)
  if((!Number(index) && index != 0) || index < 0 || index >= this.length) return null;

  // 定义初始值为头节点
  let node = this.head;

  // 筛选找到对应的节点
  while (index) {
    node = node.next;
    index -= 1;
  }
  
  return node;
}

// 方法二(为链表添加节点)
Linked_list.prototype.addNode = function (val) {  
  if (Array.isArray(val)) {
    // 先把新节点的数据处理一下
    let nodeList = [];

    // 生成节点列表
    val.forEach((item) => {
      nodeList.push(new Linked_node(item))
    })

    // 遍历新节点列表使得他们形成新的链表段
    nodeList.forEach((item, i) => {
      if (i == nodeList.length - 1) {
        item.next = null;
      } else {
        item.next = nodeList[i+1];
      }
    })

    if(this.head) {  // 存在头节点的老链表
      let prevNode = this.getNodeByIndex(this.length - 1);

      // 连接两个链表
      prevNode.next = nodeList[0] || null;
    } else { // 新链表
      // 只需要给定头节点即可连接整个链表
      this.head = nodeList[0] || null;
    }
    this.length += nodeList.length;
  } else {
      // 创建新节点
      const node = new Linked_node(val);

      if(this.head) {  // 当链表有值的时候
        // 得到当前的最后一个节点
        let prevNode = this.getNodeByIndex(this.length - 1);

        // 把当前最后一个节点的next值赋值成新添加的节点
        prevNode.next = node;
      } else {   // 当链表没值的时候
        // 把当前节点作为头节点,同时也是尾节点
        this.head = node;
      }

      // 每次添加一个新节点的时候链表长度加1
      this.length += 1;
  }
}

// 方法三(为链表添加节点,index->从哪开始,count->删除几个,newNodes->替换的节点)
Linked_list.prototype.spliceNode = function (index, count = 0, newNodes = []) {  

  // 先把新节点的数据处理一下
  let nodeList = [];

  // 生成节点列表
  newNodes.forEach((item) => {
    nodeList.push(new Linked_node(item))
  })

  // 遍历新节点列表使得他们形成新的链表段
  nodeList.forEach((item, i) => {
    if (i == nodeList.length - 1) {
      item.next = null;
    } else {
      item.next = nodeList[i+1];
    }
  })

  // 定义遍历的最终点
  let lastIndex = index + count;
  let firstPrevNode = this.head;
  let lastNode = this.head;
  let lastNextNode = this.head;

  // 找到要删除节点段的首个节点的上一个节点
  firstPrevNode = this.getNodeByIndex(index - 1);

  // 找到要删除节点段的最后一个节点
  lastNode = this.getNodeByIndex(lastIndex);

  // 找到要删除节点段的最后一个节点的后一个节点
  lastNextNode = this.getNodeByIndex(lastIndex + 1);

  if (nodeList.length) {  // 如果有新插入的新节点
    // 断开原来的链表的尾节点
    lastNode.next = null;

    // 让新的节点的首节点连接链表的断处,同时断开原来链表的首节点
    firstPrevNode.next = nodeList[0];

    // 让新的节点的尾节点连接链表的断处
    nodeList[nodeList.length - 1] = lastNextNode;

    // 改变链表的长度
    this.length = this.length - count + newNodes.length;
  } else {
    // 如果不删除节点
    if(index == lastIndex) return;
     
    // 断开原来的链表的尾节点
    lastNode.next = null;

    // 断开的链表去除删除的部分收尾再次连接
    firstPrevNode.next = lastNextNode;

    // 改变链表的长度
    this.length = this.length - count;
  }
}

// 方法四(通过节点值查找对应节点)
Linked_list.prototype.find = function (val) {
    let node = this.head;
    while (node) {
        if (node.val == val) return node;
        node = node.next;
    }
    return null;
}


// 使用方法
let linkedList = new Linked_list();
linkedList.addNode(10);
linkedList.addNode(20);
linkedList.addNode([5, 7, 9]);

JS 手写双向链表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值