给你链表的头结点 head
,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入:head = [4,2,1,3] 输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5]
示例 3:
输入:head = [] 输出:[]
代码如下:
//利用自顶而下归并排序的方法,递归地进行计算
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(head==nullptr||head->next==nullptr)
{
return head;//递归的终止条件
}
ListNode* midNode=middleNode(head);//调用寻找重点的函数,定义链表中点
ListNode* righthead=midNode->next;//定义右边链表的头节点,为中点的下一个
midNode->next=nullptr;//断开链表中点的后面,分为两个链表
ListNode* left=sortList(head);//递归,再进行分割和合并
ListNode* right=sortList(righthead);//将两个链表继续分割,合并
return mergeTwoList(left,right);//合并两个链表
}
//找到链表中点,利用快慢指针的方法
ListNode* middleNode(ListNode* head){
if(head==nullptr||head->next==nullptr)
{
return head;
}
ListNode* slow=head;//定义慢指针
ListNode* fast=head->next->next;//定义快指针
while(fast!=nullptr&&fast->next!=nullptr)
{
slow=slow->next;//慢指针每次走一步
fast=fast->next->next;//快指针每次走两步
}
return slow;//最终慢指针所指的位置就是链表的中点
}
//合并两个有序链表
ListNode* mergeTwoList(ListNode* l1,ListNode* l2)
{
ListNode *prehead=new ListNode(-1);//引入伪头节点,在头节点之前,防止头节点的丢失
ListNode *prev=prehead;//定义新的链表
while(l1!=nullptr&&l2!=nullptr)
{
if(l1->val<l2->val)
{
prev->next=l1;//当l1的值<l2的值,将l1的值添加到新的链表中
l1=l1->next;//将l1的链表节点后移
}
else
{
prev->next=l2;//当l2的值<l1的值,将l2的值添加到新的链表中
l2=l2->next;//将l2的链表节点后移
}
prev=prev->next;//使新的链表节点后移
}
prev->next=l1==nullptr?l2:l1;//在合并完两个链表之后,最多只有一个节点没有被合并,在链表末尾直接返回未被合并的链表
return prehead->next;//返回新的链表
}
};