在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list
这题目的意思就是,,,只能用
归井排序
!!!!!!!!!
/**
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
* Definition for singly-linked list->
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *findMiddle(ListNode *head)//快慢指针找出中间节点
{
ListNode *fast,*slow;
if(head==NULL)
return NULL;
slow=head;
fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
ListNode *mergeTwoList(ListNode *L1,ListNode *L2)//合并两个链表,注意合并的时候也在排序
{
if(L1==NULL)
return L2;
if(L2==NULL)
return L1;
ListNode *pre(0);//初始值为0的头节点
ListNode *head=pre;//单纯的一个节点(不推荐这么创建,但是这个变量是用于中间指向的,所以没事)
while(L1!=NULL&&L2!=NULL)
{
if(L1->val>L2->val)
{
head->next=L2;
L2=L2->next;
}
else
{
head->next=L1;
L1=L1->next;
}
head=head->next;
}
if(L1==NULL)//最后最大的一个值是没有指向的,在这里指向
head->next=L2;
if(L2==NULL)
head->next=L1;
return pre->next;
}
ListNode *sortList(ListNode *head)//递归排序 ,,画图后理解为:二分法
{
if(head==NULL||head->next==NULL)
return head;
ListNode *middle,*left,*right;
middle=findMiddle(head);//找出中间节点
if(middle==NULL)
return NULL;
right=sortList(middle->next);//第一次二分,找出链表右边的部分,然后递归,找出右边的右边。。。
//重复至只剩最右边的一个值 ,往上回去就会全部排好 最初的整个链表的右边的
middle->next=NULL;
left=sortList(head);//找出传入的链表的最左边的值,,无限递归下去就是找出两个值的左边那个
return mergeTwoList(left,right);//合并两个值 ,,变成一个链表(合成的链表依旧当成一个值好理解,)
}
};
以下是对递归的理解
归井就是二分二分二分。。。然后合并合并合并
附上链接
https://blog.youkuaiyun.com/Doutd_y/article/details/81544606