发现链表的归并排序要注意的点还真挺多。
- 对元素的划分,即要把链表从中间断开,这个可以利用一个快指针每次走两步,一个慢指针一次走一步的做法来实现,并记录前半部分链表的最后一个节点。
- 对链表的合并,这个我是利用递归,很容易理解与实现。
代码实现如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* MergeSort(ListNode* now) {
if (now == nullptr || now->next == nullptr)
return now;
ListNode* fast = now, * slow = now, * Break = now;
//注意这里一定要两个都要判断。
while (fast != nullptr && fast->next != nullptr) {
fast = fast->next->next;
Break = slow;//这里记录的是前半部分的最后一个节点。
slow = slow->next;
}
Break->next = nullptr;
ListNode* l = MergeSort(now);
ListNode* m = MergeSort(slow);
return Merge(l, m);
}
ListNode* Merge(ListNode* l, ListNode* r) {
if (l == nullptr)
return r;
else if (r == nullptr)
return l;
else if (l->val <= r->val) {
l->next = Merge(l->next, r);
return l;//注意这里要返回
}
else {
r->next = Merge(l, r->next);
return r;
}
return nullptr;
}
ListNode* sortList(ListNode* head) {
return MergeSort(head);
}
};