Sort a linked list in O(n log n) time using constant space complexity.
在O(n log n)时间对一个链表进行排序,首先想到的是几种时间复杂度为的O(n log n)排序算法,包括快排、归并排序、堆排序。
快速排序过程中,需要有两个指针指向首尾元素,并分别从首尾开始与基准元素进行比较,指针向后向前移动,比较适合双向链表;
其中归并排序比较适合单向链表的排序。
/**
* 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;
} else {
ListNode *slow = head;
ListNode *fast = head;
while(fast->next != NULL && fast->next->next != NULL) {
fast = fast->next->next;
slow = slow->next;
}
fast = slow;
slow = slow->next;
fast->next = NULL;
fast = sortList(head); // 排左半段
slow = sortList(slow); // 排右半段
return merge(fast, slow); // 归并左右排序后的结果
}
}
ListNode* merge(ListNode *head1, ListNode *head2) {
if(head1 == NULL && head2 == NULL) return NULL;
if(head1 == NULL) return head2;
if(head2 == NULL) return head1;
ListNode *ret, *p;
if(head1->val < head2->val) {
ret = head1;
head1 = head1->next;
} else {
ret = head2;
head2 = head2->next;
}
p = ret;
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) { // 如果head1还有元素
p->next = head1;
} else if (head2 != NULL) { // 如果head2还有元素
p->next = head2;
}
return ret;
}
};