在学习链表的过程中,对链表进行翻转的代码中,会出现上述代码,不容易想清楚,根据我
的理解做以下解释:
要理解这两个操作之前,我们需要明确,我们定义的节点(例如pre,next)在链表里就是链表
中某一节点本身,例如有一链表:
1->2->3->4->null;
假设有pre指向节点3,那么pre就是节点3,pre.next就是指向的节点4;
(因为我之前就是在这里卡住了很久,我之前的理解是:创建的新节点都是独立于链表之外的(这
里除了创建时已经声明创建的节点为null,如果你新建的节点初始化为null,那确实是独立于链表之
外的),导致我将上述例子理解为pre.next指向的节点就是节点3)
先申明一下变量,head头指针指向头节点,pre为null节点,next为节点;
首先来看第一句:
next = head.next
我们可以将上述式子看作赋值表达式,而赋值表达式中需要变化的量是左边的"变量",那么我
们就知道左边的"变量"next是需要进行改变的,那么变成什么呢,head.next指的是头节点的下一个
节点,所以next就变成了指向头节点的下一个节点;
然后来看下一句:
head.next = pre
这一句也当作赋值表达式看,那么变化的是head.next,也就是说本来head指针指向的下一个
节点变为指向pre节点;
当我们弄清楚上述的俩个语句,来看看链表的反转是如何进行的:
1->2->3->4->null;
我们以上述链表为例:
ListNode prev = null; ListNode curr = head; while (curr != null) { ListNode next = curr.next; curr.next = prev; prev = curr; curr = next;
首先是第一次循环:
第一步:是让next指向头节点的写一个节点,也就是节点2,此时开头的申明中已经提到,我
们可以将节点2当做next节点;
然后第二步:是将curr节点指向prev,即为null;
第三步将curr的值赋给prev,就是说prev指向curr所指向的节点,也就是节点1;
第四步是把头结点更新到next节点,也就是节点2;
此时链表状态为:
null <- 1 2 -> 3 -> 4 -> null
然后到了第二次循环:
第一步:让next节点指向下一个节点,也就是节点3
第二步:curr节点指向prev,也就是节点2指向prev节点,由于在第一次循环中,prev已经更新为节点1,所以此时节点2便指向节点1,实现了局部反转;
第三步,更新prev的位置,变为指向节点2;
第四步,更新curr位置,变为指向节点3;
之后的循环和上述操作一样,等当curr到节点4的位置,此时curr.next变为null,此时停止循环,将此反转后的链表返回:
return prev;
如有表述错误请私信我更正