手写链表反转
Node结构如下:
class Node{
public int val;
public Node next;
public Node(int data){
val = data;
next = null;
}
}
三种链表反转的方法:
1、建立虚拟头结点辅助反转
思想:使用虚拟头结点,逐个遍历链表,令元素的next=虚拟头结点的next,再将元素加到虚拟头结点之后,直至遍历完成。
先建立一个空结点ans,建立一个结点cur表示当前操作的结点,cur=head,建立一个结点next,表示cur的后一个结点,next=cur.next。遍历cur,Node next = cur.next,令cur.next = ans.next,ans.next = cur,cur = cur.next,最后返回ans.next。
2、直接操作链表实现反转
思想:直接在链表上操作,会形成方向不同的两个链表1<-2<-3 4->5->null,需要获得这两个链表的头结点Node(3)和Node(4)。对未反转的链表进行遍历,将元素作为反转链表的头结点1<-2<-3<-4 5->null。与上一种方法不同,此方法要不断更换反转链表的头结点。
先建立一个空结点pre,建立一个结点cur为当前操作结点,cur=head,建立结点next,记录cur的下一个结点。遍历cur,令next=cur.next,cur.next=pre(cur成为反转链表头结点),pre=cur(pre也成为了反转链表头结点),cur=next,最后返回pre。
3、使用递归实现链表反转
思想:使用递归可以很容易从最后的元素向前进行反转,将最后两个结点反转并返回反转的头结点,不断执行此步骤,最终获得反转链表。
先确定递归的边界,当head == null或head.next==null时返回head,即使用递归head.next得到最后一个元素(反转链表的头结点)停止,开始返回上一层的递归;新建结点newHead获得递归方法返回的结点,这层递归的head.next.next=head,head.next=null(反转head和head.next),这层反转完成,返回newHead(newHead为这层反转链表的头结点)。