清清楚楚 单链表反转(逆置)

解题考虑

1. 使用额外辅助空间的反转

这样增加了空间复杂度 ,但是实现起来比较容易,不太容易被指针的问题绕晕。
下面给出示例代码

构造链表及初始化

import java.util.Scanner;

/**
 * Created by bruce_shan on 2018/1/10 11:15.
 * Corporation CSU Software  单链表逆置
 */
public class LinkRevert {
     static class  Node
    {
        int data;
        Node next;
    }

    // 插入节点
    static void  insertNode(Node list, Node addNode)
    {
        addNode.next = list.next;
        list.next= addNode;
    }
    // 遍历链表
    static void  printList2(Node list)
    {
        while ((list.next!=null))
        {
            list = list.next;
            System.out.print(list.data + "-->");

        }
        System.out.println();
    }
    // 链表初始化
      static Node init_List()
    {
        Node list = new Node();
        list.next = null;
        Scanner scanner  = new Scanner(System.in);
        int data = scanner.nextInt();
        while (data!=-1)
        {
            Node node = new Node();
            node.data =  data;
            insertNode(list,node);
            data = scanner.nextInt();
        }
        printList2(list);
        return  list;
    }
    public static void main(String[] args) {
        Node list =  init_List();  // 链表初始化
        revert_List(list);
    }
}

解法1:一边遍历原链表一边头插法建新链表

    // 链表逆置  遍历原链表 新建一个链表头插法
    static Node revert_List(Node list)
    {
        Node newList = new Node();
        newList.next = null;
        while ((list.next!=null))
        {
            list = list.next;
            Node temp = new Node();
            temp.data = list.data;
            insertNode(newList,temp);   // 这里插入的节点直接传 list会有问题,会改变原链表
        }
        System.out.println("=====newList== ");
        printList2(newList);
        return newList;
    }

双big O(n) 解法
解法2:借助栈来实现

和解法1类似,这里不给出代码,看官自己实现一下吧。

2. 原地反转

    // 原地链表反转
    static Node revert_List2(Node list)
    {
        Node pRev = new Node();
        pRev.next = null;
        Node pTemp = list.next;
        Node pNext = pTemp;

        while(pNext!= null)
        {
            pNext = pTemp.next;
            pTemp.next = pRev.next;
            pRev.next = pTemp;
            pTemp = pNext;
        }
        printList2(pRev);
        return pRev;
    }

原地反转写法并不复杂,但是要理解清楚,就需要多画画图。

考虑初始状态,将pRev指针建头指针,将pTemp 指向原链表第一个节点(非头节点),pNext 先指向pTemp ,循环体内再指向pTemp下一个节点。

考虑中间状态,时刻记得三个指针分别承担的任务就清楚了。

这道题若还有其他挖掘的地方,欢迎大家交流讨论。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • //leetcode中还有花样链表题,这里几个例子,冰山一角 求单链表中结点的个数----时间复杂度O(n)这是最...
    暗黑破坏球嘿哈阅读 5,418评论 0 6
  • 本文内容:1、 什么是链表?2、 链表共分几类?3、 链表的 C 实现! 总表:《数据结构?》 工程代码 Gith...
    半纸渊阅读 40,144评论 0 54
  • 链表问题是面试过程中经常被问到的一部分,很考查编程功底。最近刷了 LeetCode 上链表部分的面试题,我总结了一...
    JohnnyShieh阅读 10,396评论 0 9
  • 转载请注明出处:http://www.jianshu.com/p/c65d9d753c31 在上一篇博客《数据结构...
    Alent阅读 8,823评论 4 74
  • 【声明】欢迎转载,但请保留文章原始出处→_→文章来源:http://www.jianshu.com/p/08d08...
    梦工厂阅读 9,147评论 3 31