反转链表

48 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

回顾

在上篇数组和链表中有说过,链表是一种内存分配不连续的线性结构。每一个元素存储了当前节点值和指向下一个元素的next指针。

例如,我们可以定义一个链表元素结构:

function ListNode(val, next) {
  this.val = (val===undefined ? 0 : val)
  this.next = (next===undefined ? null : next)
}

反转链表

描述

现在有一个单链表的头节点head,你需要把head链表反转,并返回。

如下:

head = [1,2,3,4,5]
返回:[5,4,3,2,1]

分析

原head链表的最后一个元素后面没有任何元素了,所以它的next指针指向的为null。我们需要做的是反转链表,那原链表的首个元素的next指针就不能再指向第二个元素了,而是指向null,这样我们就可以先初始化两个变量:next元素和当前元素。

let prev = null
let curr = head

我们肯定需要一个循环来遍历原链表。循环里面需要做的,首先是循环处理刚定义的元素next指针指向的prep值,然后将前一个元素的next值作为当前值继续循环。因为一个链表只要定义出他本身值和其next指针指向即可。

这里面有个比较重要的思路,当某个元素的next指针被改变后,当前值瞬间会被改变,如果不经常使用链表的话,可能不容易想到。如:

链表[1,2,3,4],对于首个元素1来说,它的next指针指向[2,3,4]这个链表,如果我们改变了它的next值为null,则当前元素已经被改变了,与原来next指针链已经没有关系了。

程序实现

var reverseList = function(head) {
  // 初始化
  let prev = null
  let curr = head
  while(curr) {
    // 把下一个元素存储起来
    const next = curr.next
    curr.next = prev
    // 定义当前值作为下一个元素的next指针指向值
    prev = curr
    // 处理完next指针指向元素后,再把刚存储的赋值给当前元素,继续循环
    curr = next
  }
  return prev
};