题目描述:
Sort a linked list in O(n log n) time using constant space complexity.
利用归并排序:
归并排序的思路
1)首先找到链表的中点(使用两个指针,一个一次跑一个,一个一次跑两个)
2)递归的对中点左边排序
3)递归的对中点右边排序
4)将排好序的两边合并
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
ListNode *mid = midNode(head);
ListNode *r = sortList(mid->next);
mid->next = NULL;
ListNode *l = sortList(head);
return mergeList(l, r);
}
//找到中间节点
ListNode* midNode(ListNode* head)
{
ListNode *fast = head->next;
ListNode *slow = head;
while(fast != NULL && fast->next != NULL)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
ListNode* mergeList(ListNode* head1, ListNode *head2) //合并两个有序链表
{
//ListNode *p1 = head1; //第一个链表的游标
//ListNode *p2 = head2; //第二个链表的游标
ListNode *newhead; //合并后链表的头结点
ListNode *p; //新链表的游标
if(head1 == NULL)
return head2; //链表1为空,直接返回链表2
if(head2 == NULL)
return head1;
//首先初始化新链表头结点
if(head1->val < head2->val)
{
newhead = head1;
p = newhead;
head1 = head1->next;
}
else
{
newhead = head2;
p = newhead;
head2 = head2->next;
}
while(head1 != NULL && head2 != NULL) //直到两个链表有一个遍历结束
{
if(head1->val < head2->val)
{
p->next = head1;
head1 = head1->next;
}
else
{
p->next = head2;
head2 = head2->next;
}
p = p->next;
}
//有一个遍历结束了,剩下的直接拼接到后面就行
if(head1 == NULL)
p->next = head2;
else if(head2 == NULL)
p->next = head1;
return newhead;
}
};