BM12 单链表的排序
描述
给定一个节点数为n的无序单链表,对其按升序排序。
数据范围:
要求:时间复杂度
示例1
输入:
{1,3,2,4,5}
复制返回值:
{1,2,3,4,5}
复制
示例2
输入:
{-1,0,-2}
复制返回值:
{-2,-1,0}
题解
思路:
对于链表的排序,其实也可以借鉴数组排序。比如冒泡排序、插入排序、选择排序等也可以很容易的在链表上使用。这里借鉴归并排序的思想对链表进行 排序。通过以下几个步骤完成:
- 找到链表的尾节点
- 以头尾节点为参数进行归并排序
- 归并排序:
- 找到头尾节点的中间节点,以中间节点为界将链表划分成2部分,一定要将中间节点的next指针设置为空
- 对划分后的2个链表分别使用归并排序,得到2个有序的链表
- 将2个有序链表连接起来,得到新的有序链表
- 排序完成
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;
}