自底向上的归并排序


 
class Solution 
{
public:
    ListNode* sortList(ListNode* head)
    {
        if (head == nullptr)return head;
        //记录链表的总长,便于从下往上归并计算
        int length = 0;
        ListNode *node = head;
        while (node != nullptr)
        {
            length++;
            node = node->next;
        }
        //标记哑结点
        ListNode *dummyHead = new ListNode(0, head);
        //从长度为1的子链表开始排序,每轮排序长度翻倍
        for (int subLength = 1; subLength < length; subLength *= 2)
        {
            ListNode* prev = dummyHead;
            ListNode *curr = dummyHead->next;
            while (curr != nullptr)//循环将在curr指向nullptr时断开,即对长度为subLength的链表进行排序之后结束。
            {
                //head1为需要排序的一号子链表的头
                ListNode* head1 = curr; 
             
                for (int i = 1; i < subLength && curr->next != nullptr; i++) 
                {
                    curr = curr->next;
                }
                //head2为需要排序的二号子链表的头
                ListNode* head2 = curr->next;
                //将head1断开
                curr->next = nullptr;
                curr = head2;
                //找到head2~curr的二号子链表
                for (int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++) {
                    curr = curr->next;
                }
                //记录这两个链表排序之后尾部应该连向哪里,并将二号子链表的尾部断开
                ListNode* next = nullptr;
                if (curr != nullptr)
                {
                    next = curr->next;
                    curr->next = nullptr;
                }
                //连接head1与head2,输出的是一个2*subLength长度的链表,将prev指向merged的尾部,即已经排序完毕的部分
                ListNode* merged = merge(head1, head2);
                prev->next = merged;
                while (prev->next != nullptr) 
                {
                    prev = prev->next;
                }
                //将curr指向尚未排序的部分
                curr = next;
            }
        }
        return dummyHead->next;

      
    }

    ListNode* merge(ListNode* head1, ListNode* head2) {
        ListNode* dummyHead = new ListNode(0);
        ListNode* temp = dummyHead;
        ListNode* temp1 = head1;
        ListNode* temp2 = head2;
        while (temp1 != nullptr && temp2 != nullptr) 
        {
            if (temp1->val <= temp2->val) 
            {
                temp->next = temp1;
                temp1 = temp1->next;
            }
            else 
            {
                temp->next = temp2;
                temp2 = temp2->next;
            }
            temp = temp->next;
        }
        if (temp1 != nullptr) 
        {
            temp->next = temp1;
        }
        else if (temp2 != nullptr) 
        {
            temp->next = temp2;
        }
        return dummyHead->next;
    }
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值