无序链表排序_双向链表排序算法

无序链表排序_双向链表排序算法需求给定一个无序的链表,输出有序的链表。分析链表排序比较特殊,由于不连续的性质,所以在进行排序的时候要引入外排思想,因此归并排序或者多路归并就成为了排序的选择。归并排序分为拆分、合并两个阶段:1.拆分需要拆分出链表中间节点,并赋值NULL阶段,形成两个独立的链表,直到拆分成单个节点为止。2.合并由于此时没个链表都为单节点,所以实质上是个有序链表合并问题。代码下面

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

需求

给定一个无序的链表,输出有序的链表。

分析

链表排序比较特殊,由于不连续的性质,所以在进行排序的时候要引入外排思想,因此归并排序或者多路归并就成为了排序的选择。
归并排序分为拆分、合并两个阶段:
1. 拆分
需要找出链表中间节点,并根据中间节点拆分成两个独立的链表,递归直到拆分成单个节点为止。
2. 合并
由于此时每个链表都为单节点,所以对于拆分的两个子链表实质上是有序链表合并问题。

代码

下面是示例代码

    private class Node {
        int value;
        Node next;
    }

    private Node getRandomList(int length)
    {
        Node node = new Node();
        int randomNum = (int) ((Math.random() * 100) % 100);
        node.value = randomNum;
        Node head = node;
        for(int i = 0; i < length; i++)
        {
            randomNum = (int) ((Math.random() * 100) % 100);
            Node temp = new Node();
            temp.value = randomNum;
            node.next = temp;
            node = temp;
        }

        return head;
    }

    private Node getMiddleNode(Node head)
    {
        Node index1 = head;
        Node index2 = head;
        while(index2.next != null && index2.next.next != null)
        {
            index1 = index1.next;
            index2 = index2.next.next;
        }

        return index1;
    }

    private Node mergeSort(Node head)
    {
        if(head.next == null)
            return head;

        Node middelNode = getMiddleNode(head);
        Node head1 = head;
        Node head2 = middelNode.next;
        middelNode.next = null;

        head1 = mergeSort(head1);
        head2 = mergeSort(head2);

        Node currenthead = mergeSequentialList(head1, head2);

        return currenthead;
    }

    private Node mergeSequentialList(Node head1, Node head2)
    {

        if(head1 == null)
            return head2;
        if(head2 == null)
            return head1;
        Node currentNode = null;
        if(head1.value < head2.value)
        {
            head1.next = mergeSequentialList(head1.next, head2);
            currentNode = head1;
        }
        else
        {
            head2.next = mergeSequentialList(head1, head2.next);
            currentNode = head2;
        }

        return currentNode;
    }

    private int outputListValue(Node list, StringBuffer bf) {
        // TODO Auto-generated method stub

        int i = 0;
        while(list.next != null)
        {
            bf.append(list.value + "-");
            i++;
            list = list.next;
        }
        return i;
    }


    public void main()
    {
        Node list = getRandomList(50);
        list = mergeSort(list);
        StringBuffer bf = new StringBuffer();
        int count = outputListValue(list, bf);
        String result = bf.toString();  
    }

复杂度

对于中间节点的查找,可以使用两指针不同步调方式,查找的时间复杂度为O(n)。
对于两个有序子链表合并,递归深度为最短链表深度,时间复杂度为O(n)。
由于归并排序会调用logn次,所以最终的时间复杂度为(2n)logn = O(nlogn)。

总结

无序链表排序考察的知识点比较多,首先要深刻理解归并排序的思想与应用场景,其次算法中也运用到了链表中间节点查找、两个有序链表归并等单算法,并且也要考虑单算法其中的细节。整体算法难度比较难。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/183150.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Windows系统重装Linux系统

    Windows系统重装Linux系统PC机以前是Windows系统现在重装Linux系统材料:8G以上U盘(eveything版本很大,如果U盘容量不足请选择DVD版本ISO)UltralSOLinux系统(Centos7_64_eveything.iso)tips:准…

    2022年6月28日
    51
  • crontab怎么使用_crontab配置

    crontab怎么使用_crontab配置    使用crontab你可以在指定的时间执行一个shell脚本或者一系列Linux命令。例如系统管理员安排一个备份任务使其每天都运行安装:apt-getinstallcron  (服务器环境下默认都会安装)使用:crontab-e  进入编辑页面(第一次进入会让你选择编辑器)       crontab-l  查看当前的定时任务以上是crontab的使用规则,以及定时方法的…

    2022年8月24日
    3
  • 关于Set集合去重[通俗易懂]

    关于Set集合去重[通俗易懂]上次说了List集合的去重,这次来说说Set集合的去重publicstaticvoidmain(String[]args){ HashSeths=newHashSet<>(); hs.add(“a”); hs.add(“b”); hs.add(“c”); hs.add(“a”); hs.add(“a”); for(Objectobj:…

    2022年6月7日
    45
  • html5 scrollheight,JavaScript之scrollTop、scrollHeight、offsetTop、offsetHeight等属性学习笔记…[通俗易懂]

    html5 scrollheight,JavaScript之scrollTop、scrollHeight、offsetTop、offsetHeight等属性学习笔记…[通俗易懂]全文参考:https://github.com/iuap-design/blog/issues/38、MDNclientHeight,只读clientHeight可以用公式CSSheight+CSSpadding-水平滚动条的高度(如果存在)来计算。如图,这样一个div,它的clientHeight为95,计算:50(height)+30(padding-top)+30(pad…

    2022年7月23日
    9
  • 计算机专业英语单词书,计算机专业英语词库.pdf「建议收藏」

    计算机专业英语词库计算机专业英语3000多词关键词:单词计算机专业英语1.filen.文件;v.保存文件2.commandn.命令,指令3.usev.使用,用途4.programn.程序5.linen.(数据,程序)行,线路7.displ…

    2022年4月16日
    57
  • vim/ideavim命令[通俗易懂]

    vim/ideavim命令[通俗易懂]IdeaVim插件使用技巧在IDEAIntellij小技巧和插件一文中简单介绍了一下IdeaVim插件。在这里详细总结一下这个插件在日常编程中的一些常用小技巧。供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考。当然基本的hjkl移动光标和几种常见模式等等基本概念就略过不提了。为了确保只包含常用操作,这里提到的技巧都没有从现成文档里抄,而是凭记忆列出(不常用自然就不记得了)。估计会有所遗漏,慢慢再补充。1.切换Vim模拟器状态这个插件允许设置一个快捷键一键开启或关闭,在切换模式时会同时自

    2022年10月1日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号