leetcode.23合并K个排序链表(C语言)--递归实现分治法

1、暴力法

将k个列表的元素依次整合在一个列表中,然后利用简单选择排序排除即可。

void Sort1(struct ListNode *list){
    if(list->next==NULL)
        return;
    struct ListNode *p=list->next,*q;
    struct ListNode *min;
    int temp;
    while(p){
        min = p;
        q = p->next;
        while(q){
            if(min->val > q->val){
                min = q;
            }
            q = q->next;
        }
        temp = min->val;
        min->val = p->val;
        p->val = temp;
        p = p->next;
    }
}

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize){
    struct ListNode *list = (struct ListNode *)malloc(sizeof(struct ListNode));
    list->next = NULL;
    struct ListNode *p,*q = list;
    int n=0;
    for(int i=0; i<listsSize; i++){
        while(lists[i]){
            p = (struct ListNode *)malloc(sizeof(struct ListNode));
            p->val = lists[i]->val;
            q->next = p;
            lists[i] = lists[i]->next;
            p->next = NULL;
            q = p;
            n++;
        }
    }
    Sort1(list);
    //QuickSort(list->next,0,n-1);
    //qsort(list->next, n, sizeof(struct ListNode), cmp);
    return list->next;
}

这道题很多排序算法实现起来都不简单,因为如快排,堆排这类排序需要数组的下标。而此题是一个链表。所以头疼了很久。也不能用快排来实现分治法(主要还是太菜了)。在看别人的题解时有人提出了递归实现分治法,代码如下:

2、分治法

struct ListNode* mergeKLists(struct ListNode** lists, int listsSize){
    int m;
    struct ListNode *tmp[2];
    struct ListNode*head=NULL,*point = NULL;
    if(listsSize==0)
        return NULL;
    else if(listsSize==1)
        return lists[0];
    else if(listsSize==2){
        while(lists[0] &&lists[1]){
            if(lists[0]->val < lists[1]->val){
                if(head){
                    point->next = lists[0];
                    point = point->next;
                }else{
                    head = point = lists[0];
                }
                lists[0] = lists[0]->next;
            }else{
                if(head){
                    point->next = lists[1];
                    point = point->next;
                }else{
                    head = point = lists[1];
                }
                lists[1] = lists[1]->next;
            }
        }
        if(lists[0])
            if(head)
                point->next = lists[0];
            else
                head = point = lists[0];         
        else
            if(head)
                point->next = lists[1];
            else
                head = point = lists[1];  
        return head;               
    } 

    m = listsSize/2;  
    tmp[0] = mergeKLists(lists,m);
    tmp[1] = mergeKLists(lists+m,listsSize-m);
    return mergeKLists(tmp,2);
}

仔细品一品这代码,真香!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值