【路飞】链表学习

186 阅读1分钟

介绍

是一种最简单的动态数据结构,在每一个节点里存到下一个节点的指针(Pointer),head为头部,tail为尾部 image.png

优点

真正的动态,不需要处理固定容量大问题;最后一个节点指向 null

缺点

丧失了随机访问的能力

分类

  • 单链表
  • 多链表
  • 循环链表

单链表实现

class ListNode {
  constructor(val) {
    this.val = val;
    this.next = null;
  }
}
class LinkedList {
  val;
  next;
  constructor(arr) {
    if (arr == null || arr.length == 0) {
      throw new Error("arr is null or empty");
    }
    this.val = arr[0];
    let cur = this;
    for (let i = 1; i < arr.length; i++) {
      cur.next = new ListNode(arr[i]);
      cur = cur.next;
    }
  }
  toString() {
    let cur = this;
    let str = "";
    while (cur != null) {
      str += cur.val + "->";
      cur = cur.next;
    }
    return str;
  }
}
const arr = [1, 2, 6, 3, 4, 5, 6];
const list = new LinkedList(arr);
console.log(list.toString());

力扣刷题

题目:反转链表

方式一

const reverseList = (head) => {
  let prev = null;
  let curr = head;
  let next = null;
  while (curr) {
    // 保持下一次的next
    next = curr.next;
    // 将下一个的next指向前一个
    curr.next = prev;
    // 保持前一个的值
    prev = curr;
    // 指针往后移动
    curr = next;
  }
  return prev;
};

方式二

虚拟头实现

const reverseList2 = (head) => {
  let dummy = new ListNode(-1);
  let cur = head;
  while (head) {
    // 缓存head
    cur = head;
    // 指针往后移动
    head = head.next;
    // 将下一个的next指向上一个
    cur.next = dummy.next;
    // 保存上一个的值
    dummy.next = cur;
  }
  return dummy.next;
};

方式三

递归

function reverseList3(head) {
  if (head == null) return null;
  return reverse(head)[0];
}

/**
1. 参数
2. 返回值[头节点、不为 null 的尾节点]
3. 终止条件
 */
function reverse(node) {
  if (node.next == null) return [node, node];
  const [newHead, newTail] = reverse(node.next);
  node.next = null;
  newTail.next = node;
  return [newHead, node];
}

写在最后

  • 文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞关注