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;
}
};
自底向上的归并排序
最新推荐文章于 2025-05-13 15:54:58 发布