输入一个链表,反转链表后,输出链表的所有元素。
一开始我的做法非常复杂,因为我一次变了两个指针,导致要分别判断单数个结点和偶数个结点的情况。
反转链表要解决的两个问题就是
1.结点指向它的前驱
2.头结点变为其尾结点
当反转一个结点时,假设反转i,首先需要记录它的前驱,让它指向它的前驱,还需要记录它的后继结点,否则就会造成链表的断裂,所以至少需要三个结点。
后来我整理了一下思路,发现有两种方法,一种用的是循环,一种用的是递归。
1.循环做法
/**循环做法来反转链表 * 思路是用三个指针来记录, * newCur表示现在正在反转的指针 * newNext表示newCur将要指向的指针 * newPre表示下一个要进行反转的指针 * * */public class ReverseLinkedListIterate { public static ListNode reverseLinkedList(ListNode head){ if(head==null||head.next==null){ return head; } ListNode newPre=null; ListNode newCur=head;//指向头结点 ListNode newNext=null;//指向头结点的前一个,也就是null while(newCur!=null) { newPre=newCur.next; newCur.next=newNext; newNext=newCur; newCur=newPre; } return newNext; }}
2.递归做法
因为每个节点的操作其实是相同的,就是把节点指向前驱,所以我们想到了用递归的方法,但是在最后一步要做一些处理。
public static ListNode reverseLinkedList(ListNode head){ if(head==null||head.next==null){ return head; } return reverse(null,head); } /** * * @param newNext 表示结点的前驱,该结点指向的新的结点 * @param newCurrent 表示当前结点 * @return */ public static ListNode reverse(ListNode newNext,ListNode newCurrent) { //当当前结点的下一个不为空时,即该结点不是最后一个结点时 if(newCurrent.next!=null) { //先记录该结点的下一个结点 ListNode newPrevious=newCurrent.next; //该结点指向前驱 newCurrent.next=newNext; //再把下一个结点当做当前结点。 return reverse(newCurrent,newPrevious); } //当当前结点为最后一个结点时,不需要再进行下一步了,但此时需要变换指针的指向 newCurrent.next=newNext; //再把尾结点返回。 return newCurrent; }