LeetCode 之 Sort List — C 实现

Sort List

 

Sort a linked list in O(n log n) time using constant space complexity.

对链表进行排序,要求时间复杂度为 O(nlogn),空间复杂度为 O(1)。

分析

    归并排序。

struct ListNode* mergeSort(struct ListNode* head);
struct ListNode* merge(struct ListNode* head, struct ListNode* right);
 
struct ListNode* sortList(struct ListNode* head) {
    if(!head || head->next == NULL) /*空或者只有一个节点*/
    {
        return head;
    }
    
    return mergeSort(head);
}

/****归并排序****/
struct ListNode* mergeSort(struct ListNode* head)
{
    struct ListNode *pre = head, *right = head;
    struct ListNode *p = head;
    
    if(!head || NULL == head->next)//只有一个节点,直接返回
    {
        return head;
    }
    
    while(p->next) /*二分链表*/
    {
        pre = right;
        right = right->next;
        if(p->next->next)
        {   
            p = p->next->next;
        }
        else
        {
            break;
        }
    }
    pre->next = NULL;/*链表断开成两部分分别进行归并排序*/
    
    head = mergeSort(head);   /*递归划分左半部分*/
    right = mergeSort(right); /*递归划分右半部分*/
    
    return merge(head, right);//合并
}

/********合并********/
struct ListNode* merge(struct ListNode* head, struct ListNode* right)
{
    struct ListNode *phead = head, *pright = right;
    struct ListNode *newHead = NULL, *pre = NULL;
    
    while(phead || pright)
    {
        if(phead && !pright)/*pright排序完,phead未完*/
        {
            pre->next = phead;
            pre = pre->next;
            phead = phead->next;
            continue;
        }
        if(pright && !phead)/*phead排完,pright未完*/
        {
            pre->next = pright;
            pre = pre->next;
            pright = pright->next;
            continue;
        }
        if(phead->val < pright->val)/*head较小,放入排好链表*/
        {
            if(NULL == pre)
            {
                pre = phead;
                newHead = pre;
            }
            else
            {
                pre->next = phead;
                pre = pre->next;/*排好指针后移*/
            }
            phead = phead->next;/*指向下一节点*/
        }
        else if(phead->val > pright->val)/*right较小,放入排好链表*/
        {
            if(NULL == pre)
            {
                pre = pright;
                newHead = pre;
            }
            else
            {
                pre->next = pright;
                pre = pre->next; /*排好指针后移*/
            }
            pright = pright->next;/*指向下一节点*/
        }
        else /*相等,两个都放入排链表*/
        {
            if(NULL == pre)
            {
                pre = phead;
                newHead = pre;
            }
            else
            {
                pre->next = phead;
                pre = pre->next; /*排好指针后移*/
            }
            phead = phead->next;/*phead指向下一节点*/
            pre->next = pright;
            pre = pre->next;
            pright = pright->next;/*pright指向下一个节点*/
        }
    }
    
    return newHead;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值