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

无序链表排序_双向链表排序算法需求给定一个无序的链表,输出有序的链表。分析链表排序比较特殊,由于不连续的性质,所以在进行排序的时候要引入外排思想,因此归并排序或者多路归并就成为了排序的选择。归并排序分为拆分、合并两个阶段: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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • VS2008安装失败_vs2015安装时发生严重错误

    VS2008安装失败_vs2015安装时发生严重错误因为前两天XML的作业时用VS2008做的,公司的电脑上没装,打算装一个,以前安装过N次VS2008,昨天在公司的电脑上安装提示如下错误:    当时以为是安装的同时打开了很多其他的应用程序导致的这个问题。今天在关闭其他程序的情况下重新安装,还是出错。    在百度上搜说是与office2007冲突,解决办法是卸载office2007再安装,但是我以前都是在安装

    2025年9月24日
    8
  • pycharm不显示结果_pycharm界面

    pycharm不显示结果_pycharm界面网上说是什么包问题的就说了。我遇到一个非常奇葩的问题因为你的设置可能是这样每次都在窗口右侧的工具栏那边显示。可能突然心情不佳就不显示了。然后你再把勾去掉即可。你要喜欢再点上也行。转载于:https://www.cnblogs.com/theWinter/p/8320343.html…

    2022年8月25日
    8
  • pycharm如何调试代码_pycharm调试debug入门

    pycharm如何调试代码_pycharm调试debug入门1.首先在怀疑出错的代码处的前面设置断点2.点击pycharmdebug按钮3.stepover也就是F8进行单击调试,只有光标在哪一行就是即将运行的代码只有光标跳到下一行,这一行才会执行4.运行到某一个自定义函数def的时候如果想知道里面如何运行单击stepinto(F7)然后继续stepover最后可能返回一个result回到main函数继续stepover。5.如果是嵌套函数,函数里面还有别的自定义函数可以运行到那一行时继续stepinto6.如.

    2022年8月25日
    5
  • Latex中希腊字母如何加粗和斜体

    Latex中希腊字母如何加粗和斜体Latex中希腊字母如何加粗和斜体原创不易,路过的各位大佬请点个赞一、希腊字母加粗注意:\mathbf不起作用方案一、用\usepackage{amsmath}\boldsymbol{\sigma}\mathbf只对公式中的普通字母ABC…abcdef等起作用。方案二、更好的方法是使用\usepackage{bm}\bm{}来加粗。二、希腊字母斜体注意:\textit不起作用\mit+\希腊字母如:\mit\Omega原创不易,路过的各位大佬请点个赞…

    2022年10月13日
    10
  • latex字母斜体加粗_latex加粗字体

    latex字母斜体加粗_latex加粗字体显示直立文本: \textup{文本}意大利斜体: \textit{文本}slanted斜体: \textsl{文本}显示小体大写文本:\textsc{文本}中等权重:

    2022年8月3日
    13
  • 回话控制

    回话控制

    2022年2月8日
    36

发表回复

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

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