返回

链表反转:算法入门必经之路

后端

终于搞定链表反转了,惊呼一声:妙啊!

朋友们,有没有一种算法题,你总觉得它应该很简单,却总是在面试中栽跟头?对于刚入门算法的同学来说,链表反转绝对是这一类算法题的代表。

链表反转的重要性

链表反转在算法面试中可谓是常客,各大算法题网站上都稳居前三。这并非巧合,而是因为它在链表操作中有着举足轻重的作用。链表作为一种重要的数据结构,在实际开发中应用广泛。掌握链表反转,不仅可以帮助我们理解链表的基本操作,更能为后续深入学习算法打下坚实基础。

循环反转

循环反转是链表反转最基本的方法。它的原理是:从链表的头结点出发,逐个遍历链表中的每个结点,同时将当前结点的 next 指针指向它的前驱结点,并将前驱结点作为新的头结点。

举个例子,假设原链表为 1 -> 2 -> 3 -> 4 -> 5,我们从头结点 1 开始遍历:

  • 首先,将 1 的 next 指向 null,因为它是新的尾结点。
  • 然后,将 2 的 next 指向 1,并将 2 设为新的头结点。
  • 继续遍历,将 3 的 next 指向 2,并将 3 设为新的头结点。
  • 依此类推,直到遍历到尾结点 5。

经过这一系列操作,链表就反转为 5 -> 4 -> 3 -> 2 -> 1。

递归反转

递归反转是一种更简洁优雅的方法。它的原理是:将链表的剩余部分反转,然后将当前结点插入到反转后的链表头部。

同样以原链表 1 -> 2 -> 3 -> 4 -> 5 为例:

  • 首先,我们将剩余部分 2 -> 3 -> 4 -> 5 反转(递归调用)。
  • 然后,将当前结点 1 插入到反转后的链表头部。

经过这两个步骤,链表就反转为 5 -> 4 -> 3 -> 2 -> 1。

代码示例

下面给出 Python 和 Java 语言的链表反转代码示例:

Python

def reverse_list(head):
  prev = None
  current = head
  while current:
    next_node = current.next
    current.next = prev
    prev = current
    current = next_node
  return prev

Java

public ListNode reverseList(ListNode head) {
  ListNode prev = null;
  ListNode current = head;
  while (current != null) {
    ListNode next = current.next;
    current.next = prev;
    prev = current;
    current = next;
  }
  return prev;
}

总结

链表反转是一种重要的算法,掌握它不仅有助于理解链表的基本操作,更能为深入学习算法奠定基础。循环反转和递归反转是两种常见的链表反转方法,各有优劣。对于初学者来说,循环反转更容易理解和实现,而递归反转则更简洁优雅。希望这篇文章能帮助你彻底搞定链表反转,在算法面试中不再栽跟头!