面经------单向链表反转
问题描述
现定义了如下的ListNode结构, 要求对整个List进行反转。
//Definition for singly-linked list.
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
递归解法
递归的思路是从链表的最后一个Node开始反转,创建一个newHead指向最后一个Node(cur),head指向newHead的前一个Node, 然后反转cur和head,如此逐步向前。
详细解释如下。
首先指针H迭代到底如下图所示,并且设置一个新的指针newHead作为反转后的链表的头。由于整个链表翻转之后的头就是最后一个数,所以整个过程newHead指针一直指向最后一个Node。

然后H指针逐层返回的时候如下图,将H指向的地址赋值给nextNode->next指针,并且一定要记得让H->next =NULL,也就是断开现在指针的链接,否则新的链表形成了环,下一层nextNode->next赋值的时候会覆盖后续的值。程序中的nextNode指针即为上一层返回的H->next.

第二次返回nextNode后如下图。

逐层返回:

返回到头后如下图:

代码如下:
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode nextNode = head.next;
ListNode newHead = reverseList(nextNode);
nextNode.next = head;
head.next = null;
return newHead;
}
非递归解法
非递归的方法与递归方法相反,它是从前往后顺序处理Node的。
首先设置两个新Node,P (curr)和 newH(prev)。

然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示。此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针nextTemp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=nextTemp就可以取回原链表的数据了,所有循环访问也可以继续展开下去。

指针继续向后移动,直到P指针指向NULL停止迭代。

最后一步

代码如下:
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode nextTemp = curr.next;
curr.next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
仅用于个人的学习理解,如需转载,请标明出处:
https://blog.youkuaiyun.com/sc19951007/article/details/83613598