单链表反转是当前节点与上一个节点建立关系,依次反复,最后输出新的头节点的过程。
- 准备工作:定义一个链表的节点对象:
//定义节点
public class ListNode {
public int val; //数据域
public ListNode next = null; //指针域,存放下一个节点
ListNode(int val) {
this.val = val;
}
}
- 算法分析
算法的核心在于两个
(1)如何定位新的头节点:当前节点的下一个节点为null,便是反转后链表的头;
(2)该过程就是当前节点与上一个节点建立关系的过程。建立完毕,将当前节点赋予到上一个节点,下一个节点赋予为当前节点。依次循环,直到当前节点为null;
1. 迭代法:
public ListNode ReverseList(ListNode head) {
ListNode newHead = null; //反转后的头节点
//开始处理
ListNode preNode = null; //上一节点
ListNode curNode = head; //当前节点
//当前节点为null的时候,结束循环(其实此刻preNode指向头节点)
while (curNode != null) {
//若是当前节点的下一个节点是null,则是反转后的头结点
if (curNode.next == null) {
newHead = curNode;
}
//把当前节点下一节点保存起来
ListNode nextNode=curNode.next;
//当前节点指向下一节点
curNode.next=preNode;
//节点自动前进一步
preNode=curNode;
curNode=nextNode;
}
return newHead;
}
2. 递归法:
- 使用递归方法,需先要有递归出口。即考虑到链表的特殊情况(链表就一个元素或本身就是null)
- 方法中调用header.next节点,那么这个方法返回的一定是一个反转后的头节点(newHead),而原始的头节点此时已经为尾节点,然后我要做的便是新的尾节点(head.next.next)指向反转前的head节点,然后head节点指向null。
public ListNode ReverseList(ListNode head) {
//递归出口
if (head == null || head.next == null) {
return head;
}
//完成递归,返回头结点
ListNode newHead = ReverseList(head.next);
//b.Node=aNode;
head.next.next = head;
//a.Node.next=null
head.next = null;
return newHead;
}