一、定义链表
单向链表的性质决定了,由单向链表头节点可以获取整个链表。
#针对每一步操作用注释做了解释#
public class Node {
public int value;
public Node next;
// 链表的第一个节点,next指针指向空内存
public Node(int i){
value = i;
next = null;
}
/**
* 向链表中添加新节点
* @param head 头节点
* @param add 待添加的新节点
* */
public void add(Node head, Node add){
if(head == null) return;
// 由头节点遍历至链表末尾
while(head.next != null){
head = head.next;
}
head.next = add;
}
/**
* 由头节点出发顺序遍历整个链表
* @param head 头节点
* */
public static void print(Node head){
if(head == null) System.out.println("链表为空");
while(head != null){
System.out.print((head.value + " => "));
head = head.next;
}
}
/**
* 反转链表(迭代的方式顺序逐步处理)
* @param head 头节点
* @return
* */
public static Node reverse(Node head){
if(head == null || head.next == null) return head;
Node cur = head; // 当前“指针转向”这一操作所处理的节点
Node pre = null; // 为当前所处理的节点所准备的新前驱节点
Node next = null; // 为当前所处理的节点所准备的新后继节点
while(cur != null){
next = cur.next; // 储存当前节点的后继节点
cur.next = pre; // 将当前处理的节点的next指针指向现在的前驱
pre = cur; // 当前节点会是下一次处理的节点的前驱节点
cur = next; // 将要处理的节点变换为后一个节点
}
// 最终pre会是逆序后单向链表的头节点
return pre;
}
}
二、测试Demo
public class ReverseLinkedTableTest {
public static void main(String[] args) {
Node head = new Node(0);
for(int i=1;i<=10;i++) {
head.add(head, new Node(i));
}
Node.print(head);
System.out.println();
System.out.println("================================");
Node.print(Node.reverse(head));
}
}
三、输出
0 => 1 => 2 => 3 => 4 => 5 => 6 => 7 => 8 => 9 => 10 =>
================================
10 => 9 => 8 => 7 => 6 => 5 => 4 => 3 => 2 => 1 => 0 =>
四、递归方法反转链表
Node reverseRecurrence(Node head) {
if (head.next == null) return head; // 仍然要对可能出现的空链表做预处理
Node last = reverse(head.next); // 为了方便理解,可以先假设除了头节点以外的部分已经被逆序完成
head.next.next = head; // 解释有点绕:将头节点的后继节点,的前驱,变为头节点
head.next = null; // 头节点next指针指向空内存
return last; // 由last接收逆序后的新链表
}