输入一个链表的头结点,将这个链表反转并输出它的新的头结点
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
//方法一:
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null) return null;
if(head.next==null)return head;
ListNode h1 = head;//h1指向初始头结点,最后将初始头结点的next域置空
ListNode p = null;//作为h2的下一个节点,保证未被旋转的后续节点,引用的存在
ListNode h2 = head.next; //h2总是指向下一个要被旋转的节点
while(h2.next!=null){
p =h2.next;//p指向h2的下一个节点,保证未被旋转的节点临时头结点的存在
h2.next = head;//当前旋转节点的next指向已经旋转完毕的头结点位置
head = h2;//当前头结点旋转完毕,head重新指向新的头结点
h2 = p;//h2指向下一个未被旋转的临时头结点
if(h2.next==null){//如果此时h2的next域为null,说明已经到原始链表尾部,不能在进行while循环
h2.next = head;//循环到最后一个节点时,不满足循环条件,会跳出循环,所以加了一个if
head = h2;
break;
}
}
h1.next = null;
return head;
}
}
//方法二:**(其实我写的这两个差不多,为什么要写相似的两个?因为我要学习区别使用p和p.next的区别)**
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null)return null;
if(head.next==null) return head;
ListNode p = head.next;
ListNode q = null;
boolean flag = true;
while(p!=null){//判断p是否为空
q = p.next;//注意q可能为空
p.next = head;//将新节点接入到反转的列表中
if(flag) {head.next=null;flag = false;}//把第一次头结点指向第二个节点的next域清空
head = p;//将头结点移向新接入的节点上
p = q;//将q指向未加入反转列表的临时头节点引用
// flag = false;//将标示量变为false,后续不需要将next域置空,为了优化程序把它挪到上边if中去
}
return head;//返回头结点
}
}