排序链表问题

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表

示例 1:

排序链表问题_第1张图片

输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

排序链表问题_第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->valval)
            {
                prev->next=l1;//当l1的值next;//将l1的链表节点后移
            }
            else
            {
                prev->next=l2;//当l2的值next;//将l2的链表节点后移
            }
            prev=prev->next;//使新的链表节点后移
        }
        prev->next=l1==nullptr?l2:l1;//在合并完两个链表之后,最多只有一个节点没有被合并,在链表末尾直接返回未被合并的链表
        return prehead->next;//返回新的链表
    }
};

你可能感兴趣的:(链表,算法,数据结构)