package com.lianbiao.java;
import org.junit.Test;
class three {
public static void main(String[] args) {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode head = node1;
node1.next = node2;
node2.next = node3;
ListNode last = reverseList2(head);
while(last != null) {
System.out.println(last);
last = last.next;
}
}
//
//双指针法
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;//cur和prev主要用来完成改变指针方向
ListNode temp = null;//temp作为辅助,保存变量
while(cur != null) {
temp = cur.next;//保存下一个结点
cur.next = prev; // 改变指针方向
prev = cur;//prev向前移动
cur = temp;// cur向前移动,可以想象到,prev先向前移动到cur,cur再移动到cur.next
}
return prev;//此时cur为null 退出循环,prev = 最后一个元素
}
//递归
public ListNode reverseList1(ListNode head) {
return reverse(null, head);
}
private ListNode reverse(ListNode prev, ListNode cur) {
if(cur == null) {
return prev;
}
ListNode temp = null;
temp = cur.next;//保存下一个结点
cur.next = prev;//反转
//更新prev、cur位置;
//prev = cur;
//cur = temp;
return reverse(cur, temp);
}
//
//从后向前递归
public static ListNode reverseList2(ListNode head) {
//边缘条件判断
if(head == null) {
return null;
}
if(head.next == null) {
return head;
}
//递归调用,翻转第二个结点开始往后的链表
ListNode last = reverseList2(head.next);//可以想到last的第一个值为链表的末尾
//反转头结点与第二个结点的指向,这么理解:(head.next).next = head 就是调换第二个元素与第一个元素指针方向
head.next.next = head;
// 此时的 head 节点为尾节点,next 需要指向 NULL
head.next = null;
return last;
}
}
class ListNode {
int val;
ListNode next;
public ListNode(int val) {
super();
this.val = val;
}
@Override
public String toString() {
return "ListNode [val=" + val + ", next=" + next + "]";
}
}
//从后向前递归方法说明