根据算法题目要求,看出主要考察排序算法中的归并排序,那归并排序的思想类似于分治。
简单描述为
第一步 递归,找中点,切割链表
第二步 对每个子链表操作
第三步 把排序好的子链表一步步合并
class Solution {
public:
ListNode* sortList(ListNode* head) {
return mergeSort(head); // 归并排序
}
// 递归地切割表 直达最后表只有一个或者没有一个节点 再进行合并
ListNode* mergeSort(ListNode *head)
{
if(!head||!head -> next)return head;
// 这里用快慢指针找到链表中点 快指针比慢指针每次都快一步
//当快指针到达链表尾部 慢指针到达中点
// 还可以用其他方法找到中点 比如遍历这个链表并且计数
ListNode* fast = head;
ListNode* slow = head;
ListNode* cut = head; //找到中点后 用这个指针切断链表
while(fast && fast -> next)
{
fast = fast -> next -> next;
cut = slow;
slow = slow -> next;
}
cut -> next = NULL; //此时切成俩个链表 第一表头是head 第二个表头是slow
// 分别对俩个子表进行归并排序
ListNode* l1 = mergeSort(head);
ListNode* l2 = mergeSort(slow);
return merge(l1,l2); // 把排序好的子表合并
}
// 把俩个表进行合并
ListNode* merge(ListNode* l1 , ListNode* l2)
{
// 递归到最后有空表的可能
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
// 合并 从表头开始比较 值小的作为新表头
if(l1 -> val <= l2 -> val)
{
l1 -> next = merge(l1 -> next, l2);
return l1;
}
else
{
l2 -> next = merge(l2 -> next, l1);
return l2;
}
}
};