15.反转链表
反转链表后,输出新链表的表头
本题的关键就是在于对next域的赋值,同时对下一个节点进行保存,然后对把下一个节点赋给新的节点,这样依次循环完所有的节点。每次使新插入的节点变成头第一个有效节点.如下图:
ps:如果当前节点的下一个节点为空,那么当前节点就是原链表的尾节点,也即反转后新链表的头节点
public class Solution {
public ListNode ReverseList(ListNode head) {//head为头指针--引用
//定义两个指针---引用
ListNode pre=null;
ListNode next=null;
//当前节点是head,pre为当前节点的前一节点,next为当前节点的下一节点
//需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2
//即pre让节点可以反转所指方向,但反转之后如果不用next节点保存next1节点的话,此单链表就此断开了
//所以需要用到pre和next两个节点
while(head!=null){
//先用next保存head的下一个节点的信息,保证单链表不会因为失去head节点的原next节点而就此断裂
next=head.next;//next指向(当前节点的下一个节点)
//保存完next,就可以让head从指向next变成指向pre了,代码如下
head.next=pre;//当前节点的下一个节点指向(pre)//实现反转特征
//head指向pre后,就继续依次反转下一个节点
//让pre,head,next依次向后移动一个节点,继续下一次的指针反转
pre=head;//pre指向当前节点
head=next;//当前节点指向下一个节点---实现向后移动
}
//如果head为null的时候,pre就为最后一个节点了,但是链表已经反转完毕,pre就是反转后链表的第一个节点
//直接输出pre就是我们想要得到的反转后的链表
return pre;
}
}
头指针,头结点的区别:
头指针是指指向开始结点的指针(没有头结点的情况下)。一个单链表可以由其头指针唯一确定,一般用其头指针来命名单链表。
头结点是在链表的开始结点之前附加的一个结点。有了头结点之后头指针指向头结点,不论链表是否为空,头指针总是非空,而且头结点的设置使得对链表的第一个位置上的操作与在表中其它位置上的操作一致
判断链表是否为空:
链表区分带头节点和不带头结点两种。假定链表节点指向下一节点的指针变量名为next。那么判断空链表的方法为:
1 .带头节点。
对于带头节点的链表,存在有不变的头结点head,这个节点并不保存任何数据,仅提供链表起始的一个标识。对于此类链表,判断为空的条件为:
head.next=null。当head的next值为null,这时链表为空。
2 不带头结点。
不带头结点的情况,链表的起始节点是可能变化的,但无论如何变化,必须有一个节点指针类型的变量保存实际上的第一个节点head。
当head为空时,链表即为空。这时判断为空的条件为head=null。
题目给的也没有说是有头的链表还是无头的链表(但是这里应该按照无头的链表来写)
二刷:
对于这个指针指向不是很明白,以及循环处处理:
next=head.next;首先用next将head.next节点值保存起来
head.next=pre;
pre->1->2->3->4->5->null
为实现反转,
null<-1<-2<-3<-4<-5
就是让1.next应该是null.
继续2.next应该是1
那么pre向后移动给他赋值就为当前的节点值head作为循环
pre=head;
继续把原本节点的下一个值作为当前节点
head=next;向后移动,应该把存放的下一个节点作为当前节点