前端-算法之-单链表反转

87 阅读2分钟

单链表反转

反转单个链表

输入:1>2>3>4>5>6

输出:6>5>4>3>2>1

解法1:迭代,重复某一过程,每一次处理结果作为下一次处理的初始值,这些初始值类似于状态、每次处理都会 改变状态、直至到达最终状态 从前往后遍历链表,将当前节点的next指向上一个节点,因此需要一个变量存储上一个节点prev,当前节点处理 完需要寻找下一个节点,因此需要一个变量保存当前节点curr,处理完后要将当前节点赋值给prev,并将next指 针赋值给curr,因此需要一个变量提前保存下一个节点的指针next

image-20230310103031612

代码实现

class ListNode {
  constructor(val, next) {
    this.val = val;
    this.next = next;
  }
}

const node5 = new ListNode(5, null);
const node4 = new ListNode(4, node5);
const node3 = new ListNode(3, node4);
const node2 = new ListNode(2, node3);
const node1 = new ListNode(1, node2);
const reverseList = function (head) {
  // 链表为空或只有一个节点时,不用反转
  if (head === null || head.next === null) {
    return head;
  }
  let prev = null,  // 头部节点
    next, //下个节点
    curr = head;  // 指针
  while (curr !== null) {
    next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
};

console.log(reverseList(node1));

1、将下一个节点指针保存到next变量 next = curr.next 2、将下一个节点的指针指向prev, curr.next = prev 3、准备处理下一个节点,将curr赋值给prev 4、将下一个节点赋值为curr,处理一个节点

解法2:递归:以租似的方法重复,类似于树结构,先从根节点我到叶子节点,从叶子节点开始遍历 大的问题(整个链表反转)拆成性质相同的小问题(两个元素反转)curr.next.next = curr 将所有的小问题解决,大问题即解决

image-20230310112140425

只需每个元索都执行curr.next.next = curr, curr.next =null两个步骤即可 为了保证链不断,必须从最后一个元素开始

代码实现

class ListNode {
  constructor(val, next) {
    this.val = val;
    this.next = next;
  }
}

const node5 = new ListNode(5, null);
const node4 = new ListNode(4, node5);
const node3 = new ListNode(3, node4);
const node2 = new ListNode(2, node3);
const node1 = new ListNode(1, node2);

const reverseList = function(head) {
  if (head === null || head.next === null) {
    return head;
  }
  const new_head = reverseList(head.next);  // 反转后的头节点
  head.next.next = head;                  // 将反转后的链表的尾节点与当前节点相连
  head.next = null;
  return new_head;
  
};
console.log(reverseList(node1));