面试题24:反转链表
题目描述
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点
链表结构
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
问题分析
头插法是反转链表非常经典的一种手段,这里演示一下吧,毕竟这个在JDK源码中也能遇见。
核心代码如下:
ListNode Inverse(ListNode L)
{
ListNode p, q;
p = L.next;
L.next = null;
while (p != null)
{
q = p;
p = p.next;
q.next = L.next;
L.next = q;
}
return L;
}
这些图示来自我这篇文章的单链表逆置:头插法图解,实现方面是用C语言,如果你不懂C语言,你把 -> 理解为.
刚开始是这样
循环前的操作
进入循环,分别用q和p记录第一个和第二个节点
进入第二轮循环,这是发生重大变化的关键时期
这张图调整一下
直到链表为空.
当然除了这种方法外,我们也可以用递归进行处理,我们通过递归,到达链表的尾结点,再依次对链表进行反转操作。
反转操作很简单
以最后的节点 6 为例
只需要把节点6后面的引用指向节点5,节点5的引用置为null
在处理节点5的时候,将节点5后面的引用指向节点4,节点4的引用置为null,依次处理即可
核心代码如下
head.next.next=head;
head.next=null;
三、问题解答
(1)头插法
public ListNode reverseList(ListNode head) {
if(head==null) {
return null;
}
ListNode pNode=head;
ListNode preNode=null;
ListNode nextNode=pNode.next;
while(nextNode!=null) {
pNode.next=preNode;
preNode=pNode;
pNode=nextNode;
nextNode=pNode.next;
}
pNode.next=preNode;
return pNode;
}
(2)递归
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null) {
return head;
}
ListNode rvsHead=reverseList(head.next);
//找到了最后的头结点后,开始转换每个结点的指向
head.next.next=head;
head.next=null;
return rvsHead;
}
原文地址:https://www.cnblogs.com/JefferyChenXiao/p/12246352.html
时间: 2024-10-02 16:05:13