链表排序算法_怎么对链表进行排序

链表排序算法_怎么对链表进行排序排序算法概述盗个图转自:https://www.cnblogs.com/onepixel/articles/7674659.html排序算法复杂度由于是链表排序,首先定义链表节点数据结构common.htypedefstructNodeLNode;structNode{intdata;LNode*next;LNode*prev;};备注:以下排序…

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

Jetbrains全系列IDE稳定放心使用

以下原理及实现均为个人理解,如有错误或更优解,欢迎留言指正!

排序算法概述

盗个图

转自:https://www.cnblogs.com/onepixel/articles/7674659.html

链表排序算法_怎么对链表进行排序

排序算法复杂度

链表排序算法_怎么对链表进行排序

由于是链表排序,首先定义链表节点数据结构

common.h

typedef struct Node LNode;

struct Node {
    int data;
    LNode *next;
    LNode *prev;
};
备注:以下排序算法默认由小到大排序

链表排序需要注意保证链表节点直接的连续性

  • 直接插入排序
算法简介

  1. 第一个链表节点,可以认为是已排序好;
  2. 从第二个节点开始进行排序操作,逐一向前遍历,对比节点值大小,遍历至第一个比它的值小的节点,把待排序节点插入到该节点后面;
  3. 依次对后续所有节点重复第2步操作,直至操作到最后一个节点。
算法实现
LNode* insert_sort(LNode *p) { if(NULL == p) return p; LNode *tmp = NULL; //指向待排序节点,用于节点插入 LNode *q = p, *t = q->next;// q指向待排序节点的前一个节点,t指向待排序节点 while(t) { if(q->data < t->data) { tmp = t; t = t->next; if(t) { t->prev = q; } q->next = t; while(q && (q->data < tmp->data)) { q = q->prev; } if(q) { tmp->next = q->next; q->next->prev = tmp; q->next = tmp; tmp->prev = q; } else { tmp->next = p; tmp->prev = NULL; p->prev = tmp; p = tmp; } if(t) { q = t->prev; } } else { t = t->next; q = q->next; } } return p; }

  • 归并排序

算法简介

归并排序采用分治思想,首先使其子序列成为有序序列,然后再对子序列进行归并。

递归实现:

  1. 首先把链表分割为两个子链表(采用快慢指针找到链表中间节点),递归该分割过程,直至子链表只包含一个节点为止;
  2. 创建一个新的链表节点,指向排序好的链表;对分割得到的两个子链表逐一遍历对比,值小的节点插入到新链表后面;
  3. 两个子链表归并完成,且已完成对其排序,返回链表头指针给上层递归。
算法实现
LNode *list_split(LNode *head) //分割链表,返回后一个子链表的头指针
{
    if(NULL == head)
    {
        return head;
    }

    LNode *tmp = head;
    LNode *slow = head, *fast = head; //快慢指针找到原链表的中间节点
    while(fast)
    {
        fast = fast->next;
        if(fast)
        {
            fast = fast->next;
        }

        if(NULL == fast)
        {
            break;
        }
        slow = slow->next;
    }

    tmp = slow;
    slow = slow->next;//中间节点的下一个节点作为第二个子链表的头节点
    tmp->next = NULL; //保证每个子链表尾指针都指向NULL

    return slow;
}
LNode* merge(LNode *head1, LNode *head2)//对两个链表进行归并,合为一个有序链表
{
    if(NULL == head1) return head2;
    if(NULL == head2) return head1;

    LNode head; //定义一个有序链表的头节点
    LNode *tail = &head;

    while(head1 && head2)
    {
        if(head1->data < head2->data) //将小节点插入到有序链表后
        {
            tail->next = head1;
            head1 = head1->next;
        }
        else
        {
            tail->next = head2;
            head2 = head2->next;
        }
        tail = tail->next;
    }

    if(head1) //剩下的节点要保证连接到有序链表后
    {
        tail->next = head1;
    }
    if(head2)
    {
        tail->next = head2;
    }

    return head.next; //返回有序链表的头指针
}
LNode* merge_sort(LNode *head) //归并排序入口函数
{
    if(NULL == head || NULL == head->next) //递归分割链表,直至子链表只包含一个节点为止
    {
        return head;
    }

    LNode *head1 = head; //第一个子链表头指针即链表头指针
    LNode *head2 = list_split(head); //第二个子链表头指针为中间节点的下一个节点

    head1 = merge_sort(head1); //递归第一个子链表
    head2 = merge_sort(head2); //递归第二个子链表
    return merge(head1, head2); //归并,并返回排序后链表的头指针
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • 【已解决】Win10系统点击ikbc机械键盘win键无效的解决方法

    【已解决】Win10系统点击ikbc机械键盘win键无效的解决方法一、问题描述今天周一,早上一来上班,打开电脑操作一段时间后,我想按Win+L来锁屏,发现win键按了没有任何反应,只响应了L键。设备信息描述一下:系统:Windows10键盘:ikbc怎么解决它呢?二、解决问题ikbc键盘win按键失灵问题。其实是自己不小心把win键给锁定了。下面是介绍一下ikbc键盘上,锁定win键和解锁win键的方法,如下表所示:键盘款式锁定的方法解锁的方法非静音款Fn+左WinFn+右Win静音款Fn+F12F

    2022年6月1日
    150
  • bi报表工具有哪些_bi报表工具排名

    bi报表工具有哪些_bi报表工具排名  随着现在数据量井喷式的爆发以及企业对数据的重视程度逐渐提供,高灵活性、易使用、具有高度数据治理能力的自定义bi报表工具被越来越多的人青睐,逐渐取代传统报表工具成为企业内报表平台的首选。  接下来,我们了解一下好用的bi报表工具应该具备哪些功能特性以及能力呢。  一、数据标准化能力  上面我们讲到传统报表的一个突出劣势就是对数据的标准化处理能力欠缺,影响报表的最终使用效果。很多企业标准化能力不足,主要是由于报表是由很多指标组成,企业内基本指标是固定的,但是指标的组合方式却是纷…

    2025年7月25日
    4
  • java string分割_java 字符串分割的三种方法(总结)[通俗易懂]

    java string分割_java 字符串分割的三种方法(总结)[通俗易懂]最近在项目中遇到一个小问题,一个字符串分割成一个数组,类似Stringstr=”aaa,bbb,ccc”;然后以”,”为分割符,将其分割成一个数组,用什么方法去实现呢?第一种方法:可能一下子就会想到使用split()方法,用split()方法实现是最方便的,但是它的效率比较低第二种方法:使用效率较高的StringTokenizer类分割字符串,StringTokenizer类是JDK中提供的专…

    2022年9月29日
    3
  • java零基础自学_Java零基础自学经验

    java零基础自学_Java零基础自学经验Java零基础自学经验学习Java数学不好行不行?要到能自己开发小软件的水平要多久,入门需要看些什么材料啊,网上资料不是很好,培训又要花钱,新手零基础如何自学Java比较快速?下面是由百分网小编为大家整理的Java零基础自学经验,喜欢的可以收藏一下!了解更多详情资讯,请关注应届毕业生考试网!下面分享新新人类的自学经验之谈:我学了2周了,已经入门了,基本代码都能看懂,看不懂的研究研究也就懂了。重点是…

    2022年6月20日
    29
  • Struts2 漏洞集合

    Struts2 漏洞集合Struts2漏洞集合总结了一部分Strtus2漏洞,虽然现在这部分的漏洞很少了,但也是学习的一部分,收集的并不全面,后续会做补充。漏洞环境搭建可以使用在线的 Vulfocus ,或者使用docker部署S2-001(CVE-2007-4556)该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用

    2022年7月19日
    17
  • IDEA全局查找快捷键不管用(不起作用、没反应)[通俗易懂]

    IDEA全局查找快捷键不管用(不起作用、没反应)[通俗易懂]这种情况一般都是输入法快捷键冲突请参照博客https://blog.csdn.net/weixin_44018093/article/details/91542244进行修复

    2022年6月17日
    92

发表回复

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

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