【LeetCode】148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

根据时间复杂度选择归并排序,解题思路如下:

1.使用归并排序前,找到中间节点pmiddle,因为是链表排序所以我们要找到的是中间节点的前继节点,使用快慢指针可以完成,需要注意的是分隔成两个链表时,前链表的最后一个节点指向空。

2.对前后两部分再分别进行归并排序。

3.合并两个有序链表,同样最后一个节点指向空。

ListNode* Solution::sortList(ListNode* head)
{
    if((head == NULL) || (head->next == NULL))
    {
        return head;
    }
    /*1.使用归并排序前,找到中间节点pmiddle*/
    /*前移一个节点开始寻找是为了找到中间节点的前继*/
    ListNode *pnext = new ListNode(0);
    ListNode *pmiddle = pnext;
    ListNode *pmiddlefast = pnext;
    pnext->next = head;
    while((pmiddlefast != NULL) && (pmiddlefast->next != NULL))
    {
        pmiddle = pmiddle->next;
        pmiddlefast = pmiddlefast->next->next;
    }
    /*保存中间节点的位置,中间节点的前继指向空,分隔为两个链表*/
    ListNode *part2 = new ListNode(0);
    part2 = pmiddle->next;
    pmiddle->next = NULL;
    /*2.对前后两部分列表进行排序*/
    ListNode *pfront = sortList(head);
    ListNode *prear = sortList(part2);
    /*3.合并两个有序链表*/
    ListNode *pnewhead = new ListNode(0);
    ListNode *pnew = pnewhead;
    while((pfront != NULL) && (prear != NULL))
    {
        if(pfront->val < prear->val)
        {
            pnew->next = pfront;
            pfront = pfront->next;
        }
        else
        {
            pnew->next = prear;
            prear = prear->next;
        }
        pnew = pnew->next;
        
    }
    while(pfront != NULL)
    {
        pnew->next = pfront;
        pnew = pnew->next;
        pfront = pfront->next;
    }
    while(prear != NULL)
    {
        pnew->next = prear;
        pnew = pnew->next;
        prear = prear->next;
    }
    /*注意最后节点指向空*/
    pnew->next = NULL;
    return pnewhead->next;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值