​BM12 单链表的排序​

描述

给定一个节点数为n的无序单链表,对其按升序排序。

数据范围:[链表]BM12 单链表的排序-中等_归并排序

要求:时间复杂度 [链表]BM12 单链表的排序-中等_归并排序_02


示例1

输入:

{1,3,2,4,5}

复制返回值:

{1,2,3,4,5}

复制

示例2

输入:

{-1,0,-2}

复制返回值:

{-2,-1,0}

题解

思路:

对于链表的排序,其实也可以借鉴数组排序。比如冒泡排序、插入排序、选择排序等也可以很容易的在链表上使用。这里借鉴归并排序的思想对链表进行 排序。通过以下几个步骤完成:

  • 找到链表的尾节点
  • 以头尾节点为参数进行归并排序
  • 归并排序:
  • 找到头尾节点的中间节点,以中间节点为界将链表划分成2部分,一定要将中间节点的next指针设置为空
  • 对划分后的2个链表分别使用归并排序,得到2个有序的链表
  • 将2个有序链表连接起来,得到新的有序链表
  • 排序完成
#include <bits/stdc++.h>

struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr)
{
}
ListNode() = default;
};

void swap_node(ListNode *left, ListNode *right)
{
std::swap(left->val, right->val);
}

ListNode *find_mid_node(ListNode *left, ListNode *right)
{
ListNode *slow = left;
ListNode *fast = left;
while (fast != right && fast->next != right)
{
slow = slow->next;
fast = fast->next->next;
}

return slow;
}

ListNode *link_sorted_list(ListNode *left, ListNode *right)
{
if (left == nullptr)
{
return right;
}
if (right == nullptr)
{
return left;
}
if (left->val > right->val)
{
return link_sorted_list(right, left);
}
auto head = left;
auto tail_node = head;
left = left->next;
// 这里其实是可以优化的,当某一个链表的指针为空的时候,跳出循环,然后直接让tail_node->next指向非空链表即可!!
while (left != nullptr || right != nullptr)
{
if (left == nullptr)
{
auto next = right->next;
tail_node->next = right;
tail_node = tail_node->next;
right = next;
continue;
}
if (right == nullptr)
{
auto next = left->next;
tail_node->next = left;
tail_node = tail_node->next;
left = next;
continue;
}
if (left->val <= right->val)
{
tail_node->next = left;
left = left->next;
tail_node = tail_node->next;
}
else
{
tail_node->next = right;
right = right->next;
tail_node = tail_node->next;
}
}
return head;
}

ListNode *merge_sort(ListNode *left, ListNode *right)
{
if (left == nullptr)
{
return right;
}
if (right == nullptr)
{
return left;
}
if (left == right)
{
return left;
}

auto mid_node = find_mid_node(left, right);
auto next_node = mid_node->next;
mid_node->next = nullptr;
auto pre_list = merge_sort(left, mid_node);
auto after_list = merge_sort(next_node, right);
return link_sorted_list(pre_list, after_list);
}

ListNode *sortInList(ListNode *head)
{
if (head == nullptr || head->next == nullptr)
{
return head;
}

auto cur_node = head;
while (cur_node->next != nullptr)
{
cur_node = cur_node->next;
}
return merge_sort(head, cur_node);
}

ListNode *create_list(const std::vector<int> &v)
{
ListNode head;
ListNode *phead = &head;
for (auto &data : v)
{
auto node = new ListNode;
node->val = data;
node->next = nullptr;
phead->next = node;
phead = phead->next;
}
return head.next;
}

int main()
{
// auto list = create_list(std::vector<int>{105, 25, 89, 67, 49, 38, 52});
auto list = create_list(std::vector<int>{1, 3, 2, 4, 5});
auto head = sortInList(list);
while (head != nullptr)
{
std::cout << head->val << " ";
head = head->next;
}
std::cout << std::endl;
return 0;
}