链表反转之头插法

花了半天才终于搞懂这个头插法的原理,最后还是在Visio下面画图弄明白的。。。直接上代码

 1     //单链表反转
 2     public static void reverseNode(PersonNode head){
 3         //若链表为空,则直接返回
 4         if (head.next == null || head.next.next == null) {
 5             return;
 6         }
 7         //定义一个辅助的指针,辅助遍历原链表
 8         PersonNode temp = head.next;
 9         PersonNode next = null; //指向当前节点(temp)的下一个节点
10         PersonNode reverseHead = new PersonNode(0, "", "");
11         //遍历原来的链表,每遍历一个节点,就将其取出,并放在新的链表reverseHead的最前端
12         while (temp != null) {
13             next = temp.next;   //保存当前节点的下一个节点
14             temp.next = reverseHead.next;   //将temp的下一个节点指向新的链表的最前端
15             reverseHead.next = temp;    //将temp连接到新的链表上
16             temp = next;    //让temp后移
17         }
18         //将head.next指向reverseHead.next,实现单链表的反转
19         head.next = reverseHead.next;
20     }

  先说明头插法需要两个头节点,在这里定义为初始链表的头节点head和一个空节点reverseHead,reverseHead的下一个位置为null,记住这一点。  

  这里需要说明两个指针,一个是temp指针,它用于原始链表的遍历,初始位置就是在head.next上,可以直接从这个位置进行操作;第二个指针是next,它的位置在temp指针之后的节点,可能会有疑问是为什么不直接用temp.next来表示,其实原因在于头插法在每一次的循环中都需要将temp.next指向reverseHead链表里上一次循环的头部节点处,即temp.next,每一次循环都会使temp不在与原始的head链表相连,所以就需要额外定义一个next指针来记录之前未到达的节点位置。

 

  下图是初始状态

    当执行 temp.next = reverseHead.next;时,Node1与Node2之间的连接断开,Node1.next指向Reverse链中的NULL

  

  执行reverseHead.next = temp; 时,Reverse.next指向Node1, 同时Head与Node1之间的连接也断开;


  执行temp = next;  并且进入第二次循环,temp与next都向后移一个单位

  重复上面的步骤,将之前已经舍弃的连接线省略

 

 

 

 

   可以看到,链表正在按照从后往前的顺序依次连接。

 

   

posted @ 2021-03-20 07:25  Carln  阅读(617)  评论(1编辑  收藏  举报