链表(JavaScript)----单链表(链表的基本操作,反转,是否有环)

本文介绍了一个基于LeetCode的链表实现方案,包括节点的添加、删除、查询等核心功能,并实现了链表反转及环检测等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 比较基础,不用多说了。LeetCode上链表的设计

function Linkdedlist () {
  function Node (val) {
    this.val = val;
    this.next = null;
  }
  this.head = null;
  this.length = 0;
  Linkdedlist.prototype.addAtHead = function (val) {
    var newNode = new Node(val);
    if (this.length === 0) this.head = newNode;
    else {
      newNode.next = this.head;
      this.head = newNode;
    }
    this.length++;
  }
  // 下标从0开始
  Linkdedlist.prototype.get = function (index) {
    if (this.length === 0) return -1;// 链表为空,index无论是多少都无效
    if (index < 0 || index > this.length - 1) return -1;// 链表不为空,不在链表长度范围的值都无效
    let i = 0;//记录下标的值
    let p = this.head;//移动指针
    while (i < this.length && i < index) {
      p = p.next;
      i++;
    }
    return p.val;
  }
  Linkdedlist.prototype.addAtTail = function (val) {

    let newNode = new Node(val);

    if (this.length === 0) {

      this.head = newNode;//链表为空,直接设置为头
    } else {
      let p = this.head;
      while (p.next != null) {
        p = p.next;//移动到末尾
      }
      p.next = newNode;//插入到末尾
    }
    this.length++;
  }
  Linkdedlist.prototype.tostring = function () {
    let result = '';
    let p = this.head;
    while (p) {
      result += p.val + " ";
      p = p.next;
    }
    return result;
  }
  // addAtIndex(index, val) :在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
  Linkdedlist.prototype.addAtIndex = function (index, val) {
    let newNode = new Node(val);
    if (index <= 0) {  //小于等于,插入到head前
      newNode.next = this.head;
      this.head = newNode;
      this.length++;
    } else if (index == this.length) {//等于链表长度,插入到最后
      let p = this.head;
      while (p.next) {
        p = p.next;
      }
      p.next = newNode;
      this.length++;
    } else if (index > this.length) {//超过链表长度,什么都不做
      return;
    } else {//插入到链表内部
      let p = this.head;
      let q = p;
      let i = 0;
      while (i < index) {//newNode节点,就是要插入道p,q中间的节点
        // console.log(i);
        p = q;
        q = q.next;
        i++;
      }
      newNode.next = q;
      p.next = newNode;
      this.length++;
    }
  }
  // deleteAtIndex(index) :如果索引 index 有效,则删除链表中的第 index 个节点。
  Linkdedlist.prototype.deleteAtIndex = function (index) {
    if (index < 0 || index > this.length - 1) return;
    if (this.length == 0) return;
    let i = 0;
    let p = this.head;
    let q = p;
    /**
     * 第一种情况index=0     this.head = this.head.next;
     * 第二种情况index = this.length -1 只要设置 p.next = null;(此时q为要删除的元素,即最后一个,所以q.next=null) 即p.next = q.next;
     * 第三种情况index在首末位之间   p.next = q.next;
     */
    if (index === 0) this.head = this.head.next;
    else {
      while (i < index) {
        p = q;
        q = q.next;
        i++;
      }
      p.next = q.next;

    }
    this.length--;
  }
  // 下面是新加的方法,没有用到上面中
  Linkdedlist.prototype.size = function () {
    return this.length;
  }
  Linkdedlist.isEmpty = function () {
    return this.length === 0 ? true : false;
  }
// 链表的反转
  /**
   * 将链表 分为两部分 , 一部分是反转的 , 部分是还未反转的 , 初始化的时候,p和q是在未进行反转的头部,而this.head这一个节点是反转的头部
   * p是要插入到this。head之前的节点 , q是在未进行
   */
  Linkdedlist.prototype.reversalList = function () {
    if (this.length === 0) return false;
    if (this.length === 1) return;
    let p = this.head.next, q = p;
    this.head.next = null;
    while (p) {
      q = p.next;
      // p.next = null;//先将q指到下一个节点,然后再将p从该链表中断开 , 这步断开p.next时为了更好理解
      p.next = this.head;//将断开的p追加到头结点
      this.head = p;
      p = q;//将p追加到头结点之后,要将p指针再次指向q,进行下一轮
    }
  }
  // 判断链表中是否有环(快慢指针)
  Linkdedlist.prototype.hasCircle = function () {
    if (this.length <= 1) return false;
    let fast = this.head, slow = this.head;
    while (fast.next && fast.next.next) {
      fast = fast.next.next;
      slow = slow.next;
      if (fast === slow) {
        return true;
      }
    }
    return false;
  }
}

let list = new Linkdedlist();
list.addAtHead(1);
list.addAtTail(3);
list.addAtIndex(1, 2);
// console.log(list.tostring());
console.log(list.get(1));
list.deleteAtIndex(1);
// console.log(list.tostring());
console.log(list.get(1));
// list.addAtTail('zxx');
// list.addAtHead('mmm');
// list.addAtTail('nnn');
// list.addAtTail('ooo');
// console.log(list.tostring());
// console.log(list.get(1));
// console.log(list.get(2));
// console.log(list.get(4));
// console.log(list.get(5));
// console.log(list.get(-1));
// list.deleteAtIndex(0);
// console.log("delete:", list.tostring());
// list.deleteAtIndex(3);
// console.log("delete:", list.tostring());
// list.deleteAtIndex(1);
// console.log("delete:", list.tostring());

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值