链表排序——归并排序

时间:2019-01-19
本文章向大家介绍链表排序——归并排序,主要包括链表排序——归并排序使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

排序基本原理https://blog.csdn.net/qq_28114615/article/details/86345717

1.实现思路

       与数组归并排序相同,主要分为以下三个步骤:

      ①找到链表中点。最常用的方法是双指针法;

      ②递归左半链表及右半链表。数组有很好的随机访问特点,因此传递索引来实现递归左子区间和右子区间;而在链表中,是顺 序访问的,但是链表的插入删除是很方便的,因此考虑直接将链表从中间“打断”,然后递归“打断”后的两个链表。

      ③合并链表。经②后的两个链表递归结束后必定都是有序的,因此这里就是对两个有序链表进行合并,可参考此处。另外一  种方法是递归合并,升序递归中,先找到两个链表中较小结点所在链表,将该链表剩下部分与另一个链表进行递归合并即可。

2.代码实现

ListNode* sortList(ListNode* head) {
        
        if(!head||head->next==NULL)return head;
        
        ListNode* slow=head;    //慢指针
        ListNode* fast=head;    //快指针
        
        while(fast->next&&fast->next->next)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        
        ListNode* breakNode=slow->next;  //断点 
        slow->next=NULL;  //打断结点
        
        ListNode* l=sortList(head); //递归左链表
        ListNode* r=sortList(breakNode); //递归右链表
        
        return mergeList(l,r);  //合并链表
        
    }
    
    ListNode* mergeList(ListNode* l1,ListNode* l2)
    {
        if(!l1)return l2;   
        if(!l2)return l1;
        

        if(l1->val<l2->val)
        {
            l1->next=mergeList(l1->next,l2);  //l1当前结点值较小,则递归合并剩下的部分与l2
            return l1;
        }
        else 
        {
            l2->next=mergeList(l2->next,l1); //l2当前结点值较小,则递归合并剩下的部分与l1
            return l2;
        }
        
        return NULL;    
        
    }