题目:给你链表的头节点head,请将其按照升序完成排列并返回排序后的链表。
示例:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
解题思路:
使用归并排序分别将原链表的子链表进行排序,但是有个问题,就是得先知道该链表的中间节点。
可以通过快慢指针的方式找到中间节点,慢指针每次走一步,快指针每次走两步,当快指针到达
链表的尾节点时,慢指针所指向的节点便是所需要的中间节点。
最后,当各个子链表排序完毕后,分别将其两两融合即可得到最后的排好序的升序链表。
代码:
class solution{
public:
ListNode* sortList(ListNode* head){
return sortList(head, nullptr);
}
ListNode* sortList(ListNode* head, ListNode* tail){
if (head == nullptr){
return head;
}
if (head->next == tail){
head->next = nullptr;
return head;
}
//利用快慢指针找到用于“分割链表的中间节点”
ListNode* slow = head, * fast = head;
while(fast != tail){
slow = slow->next;
fast = fast->next;
if (fast!=tail){
fast = fast->next;
}
}
ListNode* mid = slow;
return merge(sortList(head, mid), sortList(mid, tail));
}
//将排序完成的两个子链表进行融合
ListNode* merge(ListNode* head1, ListNode* head2){
ListNode* dummynode = new Listnode(0);
ListNode* tmp = dummynode, *tmp1 = head1, *tmp2 = head2;
while(tmp1 != nullptr && tmp2 != nullptr){
if (tmp1->val <= tmp2->val){
tmp->next = tmp1;
tmp1 = tmp1->next;
}else{
tmp->next = tmp2;
tmp2 = tmp2->next;
}
tmp = tmp->next;
}
if (tmp1!=nullptr){
tmp->next = tmp1;
}else if (tmp2!= nullptr){
tmp->next = tmp2;
}
return dummynode->next;
}
}