前言
单链表反转是程序员必备的基本素养,经常在面试,笔试的过程中出现。理通实现思路,代码实现并不难。
首先我们来了解一下单链表结构。单链表是一种常见的数据结构,由多个结点连接而成,每个结点后面都会跟一个指针,指向下一个结点的内存地址。所以,每一部分就是有一个数据域和一个指针域构成。
LeetCode的反转链表原题描述:
题目描述:反转一个单链表
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
分析:
在遍历链表时,将当前结点的next指针改为指向前一个结点。由于结点没有引用其上一个结点,因此必须事先存储其前一个结点。在更改引用之前,还需要另一个指针来存储下一个结点,最后返回新的头引用。
编写思路:
所谓的单链表反转就是将链表的指针方向改变。但是,由于单链表没有指向前一个结点的指针,所以我们定义一个指向前一个结点的指针prev,用于存储每一个节点的前一个结点。接下来还需要定义一个保存当前结点的指针curr,以及下一个节点的nextTemp。定义好之后,遍历单链表,将当前结点的指针指向前一个结点,之后定义三个指针向后移动,直至遍历到最后一个结点为止。
迭代法
定义一个LinkedNode:
public class LinkedNode {
Integer id;
LinkedNode next;
public LinkedNode(Integer id) {
this.id = id;
}
// 打印链表
public void print(){
System.out.print(this.id);
if (this.next != null) {
System.out.print("->");
this.next.print();
} else {
System.out.println();
}
}
}
迭代法实现方式:
public class NodeList {
public static void main(String[] args) {
LinkedNode node1 = new LinkedNode(1);
LinkedNode node2 = new LinkedNode(2);
LinkedNode node3 = new LinkedNode(3);
LinkedNode node4 = new LinkedNode(4);
LinkedNode node5 = new LinkedNode(5);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
// 打印链表
System.out.println("链表:");
node1.print();
LinkedNode resNode = reverseList(node1);
// 打印之后的链表
System.out.println("反转之后的链表为:");
resNode.print();
}
/***
* 迭代反转
* @param head
* @return
*/
public static LinkedNode reverseList(LinkedNode head) {
LinkedNode prev = null;
LinkedNode curr = head;
while (curr != null) {
LinkedNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
}
执行后的结果:
递归法
定义的LinkedNode同上面迭代法一样,这里就不赘述了。
public class NodeList {
public static void main(String[] args) {
LinkedNode node1 = new LinkedNode(1);
LinkedNode node2 = new LinkedNode(2);
LinkedNode node3 = new LinkedNode(3);
LinkedNode node4 = new LinkedNode(4);
LinkedNode node5 = new LinkedNode(5);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
// 打印链表
System.out.println("链表:");
node1.print();
LinkedNode resNode = reverseList(node1);
// 打印之后的链表
System.out.println("反转之后的链表为:");
resNode.print();
}
/**
* 递归反转
*/
public static LinkedNode reverseList(LinkedNode node) {
// 如果为空链表或者只有一个节点的链表则不需要处理
if (node == null || node.next == null) {
return node;
}
// 递归直到找到尾结点
LinkedNode newHead = reverseList(node.next);
// 尾节点反指
node.next.next = node;
// 当前节点指向null节点
node.next = null;
return newHead;
}
}
运行结果: