反转链表(java实现)

剑指offer(第16题)

与链表相关的问题总是有大量的指针操作,而指针操作的代码总是容易出错的,所以很多笔试,面试都有与链表相关的题目,就是想通过指针操作来考察其编码功底,当然,为了避免出错,在我们写代码之前应该进行全面的分析.
  • 在这里直接看图,因为需要反转链表,所以必须在反转之前把下一个节点保存起来,这里定义了三个指针(为什么定义三个,小伙伴可以自己思考一下)
    index:正在处理的节点
    next:正在处理节点的后一个节点
    second:正在处理节点的后两个节点
    在这里插入图片描述
    使第二个节点的指针指向第一个节点,并且第一个节点指针赋为null(只有第一个节点需要).
    在这里插入图片描述
    三个节点依次向后移.
    在这里插入图片描述
    就这样如此循环往复即可.当然这里还需要注意两种情况
  • 该链表只有一个节点,那么可以直接返回该节点
  • .如果该链表长度为0,也就是头结点的指针也为空,我们的代码也应该能 处理这种情况.

下面附上代码.


/**
 * 反转链表,并返回反转链表后的头节点.
 *   思路:
 *     给三个指针,分别指向正在处理的节点.
 *                    正在处理节点的后一个节点
 *                    正在处理节点的后两个节点
 *     因为在对指针修改之前,需要保存之前的值.修改了某一个节点后,三个指针依次往后移即可.
 *
 *   需要考虑两点:
 *     1.链表只有一个节点的情况.
 *     2.输入头节点为null
 */
public class Question16 {
    public static void main(String[] args) {
        //这里只是我自己以前实现的链表,直接拿来用,小伙伴可以写一个简单的节点类.
        MyLinkedList<Integer> list = new MyLinkedList<>();
        //增加节点方法,在第0位,增加存储内容为数字0的节点
        list.add(0,0);
        list.add(1,1);
        list.add(2,2);
        list.add(3,3);
        list.add(4,4);
        MyLinkedList.Node firstNode = invertList(list.getNode(0));
        while(firstNode!=null){
            System.out.println(firstNode.e);
            firstNode = firstNode.nextNode;
        }
    }
    private static MyLinkedList.Node invertList(MyLinkedList.Node first) {
        if(first==null)
            return null;
        //有一个节点的情况
        if(first.nextNode==null)
            return first;
        MyLinkedList.Node index=first; //依次指向链表中的所有节点
        MyLinkedList.Node next=first.nextNode; //指向正在处理节点的后一个节点.
        MyLinkedList.Node second=next.nextNode; //指向正在处理节点的后两个节点.
        //有两个或两个以上的节点,注意这里不能以second作为循环条件,否则就会落下最后一个节点
        while(next!=null){
            if(index==first) index.nextNode=null;
            //后一个节点的指针指向当前节点
            next.nextNode=index;
            //三个指针依次向后移
            index=next;
            next=second;
            if(second!=null)
            second=second.nextNode;
        }
        return index;
    }
}

输出结果,如图:
在这里插入图片描述

  • 其实这只是其中一种方法,另一种方法是通过递归实现的,也就是直接从最后一个节点开始处理,这时候就不再需要节点来保存了,因为递归其实是用栈实现的,栈这种数据结构帮我们保存了这些信息,如果伙伴想看代码,可以再评论中指出.
  • 最后如果对代码中某些地方有疑问,或者感觉有些不妥之处,或者也想看MyLinkList的完整代码,都非常欢迎在评论中指出,谢谢.
Tmi
发布了13 篇原创文章 · 获赞 7 · 访问量 2200

猜你喜欢

转载自blog.csdn.net/wangliangluang/article/details/101171670