0
点赞
收藏
分享

微信扫一扫

C语言实现力扣23题合并K个升序链表

C语言实现力扣23题合并K个升序链表_链表

采用暴力破解

大概思路:

1、把数组中的链表取出来放到新链表中

2、采用归并把新链表中的数据进行排序

归并排序的思路:

1、找到中间节点

2、根据中间节点,把他们分为左右区间,然后再执行第一步,第二步,直到分别只剩下一个节点

3、两个两个排序,四个四个排序,直到为有序链表

代码上有具体的讲解,原谅初学者可能分析的不到位

struct ListNode* _MergeSort(struct ListNode* left,struct ListNode* right){    

//创建新链表,把左右区间的链表合并

    struct ListNode* newlist=(struct ListNode*)malloc(sizeof(struct ListNode));

    struct ListNode* new=newlist;

    //任意一边为空都结束

    while(left && right)

    { 

       if(left->val< right->val)

        {

            new->next=left; 

           left=left->next;

        }

        else

        {

            new->next=right;

            right=right->next;

        }

        new=new->next;

    }

    //当左区间还有链表直接链接到新链表中

    if(left)

    {

        new->next=left;

    }

    //当右区间还有链表直接链接到新链表中

    if(right)

    { 

       new->next=right;

    }

    //打印

    new=newlist->next;

    while(new)

    { 

       printf("%d ",new->val);

        new=new->next;

    }

    return newlist->next;

}

struct ListNode* MergeSort(struct ListNode* head)

{

    //如果只有一个节点,那返回头节点

    if(head->next==NULL)

     {

        return head;

    }

    //使用快慢指针,找到中间节点

    struct ListNode* fast=head;

    struct ListNode* slow=head;

    struct ListNode* cur=NULL;

    while(fast && fast->next)

    {

        cur=slow;

        slow=slow->next;

        fast=fast->next->next;

    }

    //cur (左)为 slow(右)中间节点的前一个节点,把 cur 与 slow 分割开

    // 一开始在这里犯了个错,cur=slow->next ,slow->next=NULL 看出这里的问题了吗,这样写会造成死循环 ,

    // 如果把slow 归到左区间,那么只有两个节点的链表 想想看是不是就会因为结束条件为 head->next==NULL 不能执行 造成死循环

    cur->next=NULL;

    struct ListNode* left=MergeSort(head);//递归左区间

    struct ListNode* right=MergeSort(slow);//递归右区间

    return _MergeSort(left,right);//对左右区间排序

}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize)

{

    if(lists==NULL) return NULL;

    if(listsSize==0) return NULL;// lists=[] 时返回

    struct ListNode* newlist=(struct ListNode*)malloc(sizeof(struct ListNode));

    newlist->val=0;

 // 随便给头节点一个初始值

    struct ListNode* new=newlist;

    //把lists数组中的链表合并到一个新链表中

    // [[1,4,5],[1,3,4],[2,6]] ==> [ 

   //                                     1->4->5, // 0行

    //                                    1->3->4, // 1行

    //                                    2->6     // 2行

    //                                ]

    for(int i=0;i<listsSize;i++)

    {

        while(lists[i])

        {

            new->next=lists[i];

            lists[i]=lists[i]->next;

            new=new->next;

        }

    }

    // newlist是带头节点 所以它的 0(为头节点)->1->4->5->1->3->4->2->6

    if(newlist==new) return NULL;//当lists=[[]] 时,说明新链表只有一个表头

    //打印新链表

    new=newlist->next;

    while(new)

    { 

       printf("%d ",new->val);

        new=new->next; 

   } 

   return MergeSort(newlist->next);//采用归并排序

}


举报

相关推荐

0 条评论