Sort a linked list in O(n log n) time using constant space complexity.
https://oj.leetcode.com/problems/sort-list/
使用归并排序对单链表进行排序,
1> 首先使用快慢指针得到单链表的中间位置, 将单链表分成两部分。
比如原单链表是 1 -> 6 -> 4 ->3 -> 5 ->2;
分割后变成 1 -> 6 -> 4 和 3 -> 5 ->2 两个链表。
2> 分别对分割后的两个链表进行排序。
for example: 1->4->6, 和 2 -> 3 -> 5
3> 对已经排好序的两个单链表进行合并操作。
code:
/**
* 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) {
//using merge sort method to sort the singly-linked list
if (!head || !head->next) {
return head;
}
//split the list into two lists, for example:
// 1 -> 4 -> 6 ->3 -> 5 ->2 will be splited into
// 1 -> 4 -> 6 and 3 -> 5 -> 2.
ListNode *mid = getMiddle(head);
ListNode * head_second_list = mid->next;
mid->next = NULL;
return mergeTwoLists(sortList(head), sortList(head_second_list));
}
ListNode *mergeTwoLists(ListNode *list_1, ListNode *list_2) {
// now list_1 and list_2 are ordered lists
if (!list_1) {
return list_2;
}
if (!list_2) {
return list_1;
}
ListNode *head = NULL;
ListNode *tail = NULL;
// set the head
if (list_1->val < list_2->val) {
head = list_1;
list_1 = list_1->next;
} else {
head = list_2;
list_2 = list_2->next;
}
tail = head;
//start merge the two lists
while (list_1 && list_2) {
if (list_1->val < list_2->val) {
tail->next = list_1;
list_1 = list_1->next;
} else {
tail->next = list_2;
list_2 = list_2->next;
}
tail = tail->next;
}
if (list_1) {
tail->next = list_1;
}
if (list_2){
tail->next = list_2;
}
return head;
}
ListNode * getMiddle(ListNode *head)
{
//get the middle of list
if (!head || !head->next) {
return head;
}
ListNode *slow = head;
ListNode *fast = head;
while ((fast->next != NULL) && (fast->next->next != NULL)) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}