算法结构反转链表

Posted 小飞快飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法结构反转链表相关的知识,希望对你有一定的参考价值。

在牛客上刷题,top1的算法题就是反转链表,准备练习下,上链接

算法描述

输入一个链表,反转链表后,输出新链表的表头。

输入输出

输入:

{1,2,3}

输出

{3,2,1}

简要说明

首先解释下链表(自己理解的),链表即为一种 数据节点并指向下一个节点的数据结构,例如:1->2->3,即有节点 1、2、3,并且 1 指向2,2指向3;反转链表则是将1->2->3的结构反转为 3->2->1 的结构。

具体实现

先上链表的实体对象

public class ListNode {
	    int val;
	    ListNode next = null;

	    ListNode(int val) {
	        this.val = val;
	    }
	    
	    @Override
	    public String toString() {
	       ListNode curNode = this;
	       String msg="";
			while(curNode != null) {
				msg += curNode.val + "->";
				curNode = curNode.next;
			}
			return msg;
	    }
}
1、普通迭代法
public class Solution {
    public ListNode ReverseList(ListNode head) {
          //先判断是否为空或者下个节点是否为空
          if(head == null || head.next == null){
              return head;
          }
          //例如 条件head 为 {1,2,3}
          //定义结果
          ListNode result=null;
          //中间结果
          ListNode temp =null;
          //循环操作
          while(head != null){
                 //将下一个节点放到临时结果中
                 //第一次循环 temp = {2,3}
                 //第二次循环 temp = {3} 
                 //第三次循环 head 没有下个节点了,temp = null了
                temp = head.next;        
                //然后将下个节点赋值为结果节点
                //第一次循环 head = {1}; 就将下个节点清空
                //第二次循环 head = {2,1} 将下个节点3 改为 1了
                //第三次循环 head = {3,2,1}
                head.next = result;
                //将head 赋值给结果节点
                //此时的结果的下个节点已发生改变变为上个节点了
                //第一次循环 result = {1}
                //第二次循环 result = {2,1} 
                //第三次宣汉 result = {3,2,1} 
                result = head;
                //将head 赋值 为下一个节点,即为刚刚保存的临时节点
                //第一次循环 head = {2,3}
                //第二次循环 head = {3}
                //第三次循环 head 也为空了,然后就跳出循环
                head =temp;
          }
          return result;
        }
}

2、递归法

public class Solution {
    public ListNode ReverseList(ListNode head) {
          //先判断是否为空或者下个节点是否为空
          if(head == null || head.next == null){
              return head;
          }
          //递归到链表尾部
         ListNode result = ReverseList(head.next);
         // 递归出栈时链接节点
         // 下面这两句代码是最关键的也是最难以理解的
         //比如:  1->-2->null ,下面的意思将 1与2 的方向掉转  即 2->1
         //具体是  1的下一个节点是2 ,然后head.next.next = head 将 2的下一个节点指向 1
         //那么现在 1->2 而且 2->1 这种相互指向的关系,然后通过 head.next = null 就想 1 -> null 就顺利掉转方向
         head.next.next = head;
         head.next = null;
          return result;
        }
        //对整个过程再特别分析说明下
        //首先是  1->2->3->4->5-> 的结构
        //然后执行 ReverseList 方法,如果不为空,会继续执行 ReverseList,直到返回最后的 5-> 节点,其中的过程将会压栈,等到最后的返回后,再出栈
        //首先出现的 倒数第二个的  4->5->, 首先 执行 head.next.next = head 的意思就是掉头,及 4->5->4 ,然后执行head.next = null 就成了 5->4->
        //然后就是 倒数第三个的 3->4->5-> 由于上一步已经是  5->4 了,就是 3->4<-5,执行 反转操作后就是 3<-4<-5,即 5->4->3->
        //继续下去 就是按照此逻辑 就是 5->4->3->2->1->
        //有点不好理解的是,明明改变的 head 对象,返回的 result 却也在改变,只是因为始终都是在操作一个对象,在入栈的最后一步就是讲 head指向了 result了
}

总结

作为一个很经典的算法,还是得学习下,对于解决实际开发中的问题或者面试都是特别有用的,最开始很不理解递归法,最后通过画图的方式将逻辑运行过程列出来或者看看其他博主的文章就会豁然开朗。

今天的分享就这些,欢迎留言讨论哟

以上是关于算法结构反转链表的主要内容,如果未能解决你的问题,请参考以下文章

算法结构反转链表

算法结构反转链表

数据结构与算法6-链表下

Java数据结构和算法—算法—反转链表

数据结构与算法-链表反转带头节点

数据结构和算法之单向链表六:链表的反转以及链表节点的删除