题目:Sort a linked list in O(n log n) time using constant space complexity.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//数组存储的归并排序 时间复杂度O(nlogn)空间复杂度 O(n)
//链表存储的归并排序 时间复杂度O(nlogn)空间复杂度 O(1)
//找到链表中间位置
ListNode *find_middle(ListNode *head)
{
//使用快,慢指针的方法:慢指针走一步,快指针走两步
ListNode *slow = head;
ListNode *fast = head;
//三个条件都满足才能行,否则对于两个元素不能平分
while(fast != NULL && fast->next != NULL && fast->next->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
//合并两个有序链表:前提是两个链表本身必须有序
ListNode *merge_list(ListNode *arg_left, ListNode *arg_right)
{
if(arg_right == NULL)
{
return arg_left;
}
//左链表当前节点的上一个节点
ListNode *pre_left = arg_left;
ListNode *left = arg_left;
ListNode *right = arg_right;
while(left != NULL && right != NULL)
{
if(left->val > right->val)
{
//为减少内存开辟,直接将右链表小值插入左链表中
if(left == arg_left)
{
arg_left = right;
ListNode *tmp_right = right;
right = right->next;
tmp_right->next = left;
pre_left = tmp_right;
}
else
{
ListNode *tmp_right = right;
right = right->next;
pre_left->next = tmp_right;
tmp_right->next = left;
pre_left = tmp_right;
}
}
else
{
pre_left = left;
left = left->next;
}
}
if(left == NULL)//如果左链表遍历完
{
pre_left->next = right;
}
return arg_left;
}
ListNode *sortList(ListNode *head) {
//归并排序
if(head == NULL || head->next == NULL)
return head;
ListNode *middle = find_middle(head);
ListNode *right = sortList(middle->next);
middle->next = NULL;
ListNode *left = sortList(head);
return merge_list(left, right);
}
};