Sort a linked list in O(n log n) time using constant space complexity.
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
归并排序,每次找到链表的中间结点,拆分后,分别排序,合并。
class Solution {
public:
ListNode * merge(ListNode*left,ListNode*right){
if(right==NULL)
return left;
if(left==NULL)
return right;
// ListNode * root=malloc(sizeof(Node));
ListNode * root=NULL;
if(left->val<right->val){
//root->val=left->val;
root=left;
root->next=merge(left->next,right);
}else{
//root->val=right->val;
root=right;
root->next=merge(left,right->next);
}
return root;
}
ListNode *sortList(ListNode *head) {
if(head==NULL ||head->next==NULL) return head;
ListNode*slow=head;
ListNode*fast=head;
while(fast!=NULL && fast->next!=NULL && fast->next->next != NULL){
fast=fast->next->next;
slow=slow->next;
}
ListNode* head2=slow->next;
slow->next=NULL;
return merge(sortList(head),sortList(head2));
}
};
1)对fast指针的边界的判断,对NULL->next是错误的,
2)merge有两种方式,递归与非递归,下面是非递归的做法
ListNode * merge(ListNode*left,ListNode*right){
if(right==NULL)
return left;
if(left==NULL)
return right;
// ListNode * root=malloc(sizeof(Node));
ListNode * root=NULL;
ListNode * tail=NULL;
if(left->val<right->val)
{
root=left;
left=left->next;
}
else{
root=right;
right=right->next;
}
tail=root;
while(left!=NULL && right!=NULL){
if(left->val<right->val){
tail->next=left; //链接
tail=tail->next; //移动尾指针
left=left->next; //链表移动
}else{
tail->next=right;
tail=tail->next;
right=right->next;
}
}
if(left!=NULL){
tail->next=left;
}else{
tail->next=right;
}
return root;
}
本文介绍了一种使用归并排序算法对链表进行排序的方法,该方法能够在O(nlogn)的时间复杂度内完成排序,并且仅使用常数级别的额外空间。通过找到链表的中间节点将其拆分为两部分,递归地对这两部分进行排序,然后将它们合并为一个有序链表。
2306

被折叠的 条评论
为什么被折叠?



