您的位置:首页 > 其它

翻转单向链表

2017-11-08 19:15 162 查看
首先给出对单链表的节点类的定义:

public class ListNode{
private int val;
private ListNode next;
public ListNode(int val){
this.val = val;
this.next = null;
}
}


翻转单链表有两种方法,递归和遍历。

遍历法:

定义两个指针,一个pre指向当前节点的前一个节点,一个now指向当前节点。

只要当前节点不为空,定义一个tmp节点保存now.next,并将now指向pre,同时将pre和now分别向前推进。

当now节点为空时,返回pre(因为此时的pre和now已被向前推进)。

public ListNode reverse(ListNode head){
if(head == null){
return null;
}
ListNode pre = null;
ListNode now = head;
while(now != null){
ListNode tmp = now.next;
now.next = pre;
pre = now;
now = tmp;
}
return pre;
}


递归法:

刚开始想了很久都没想清楚,后来发现是对递归的执行顺序理解有误。

顺便复习一下递归的执行顺序:(以此题为例)(假设链表为0->1->2->3->4)

1.执行递归调用前的语句

2.执行reverseList(1) 

3.继续执行递归调用前的语句

4.执行reverseList(2)

...

5.执行reverseList(4),此时return head(为4)给rest

6.重复执行递归调用后的语句,直到回到reverseList(0),该过程相当于不断把节点挨个翻转。

总之就是:

递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序;位于递归调用后的语句的执行顺序和各个被调用函数的顺序相反。

public ListNode reverseList(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode rest = reverseList(head.next);
head.next.next = head;
head.next = null;
return rest;
}


总结一下递归法:先找到最后一个非空节点,然后调用递归,从最后一个节点开始挨个翻转节点。

最后为了方便,记录一下随便写的用于单链表的测试代码:

public static void main(String[] args) {
ReverseListNode2 R = new ReverseListNode2();
ListNode head = R.new ListNode(0);
ListNode cur = head;
for(int i = 1; i < 4; i++){
ListNode node = R.new ListNode(i);
cur.next = node;
cur = node;
}
System.out.println(R.reverseList(head).val);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  lintcode 单链表