Sort a linked list in O(n log n) time using constant space complexity.
对一个链表进行排序的操作
在排序的问题在博客的算法部分做了一些介绍包括插入,希尔,快排,归并
其中题目要求了时间复杂度和空间复杂度,我们首选归并排序
归并排序的空间复杂度为O(N),而快排的空间复杂度不是很稳定,可能主要是因为pivot的不稳定
先实现归并的算法,之后尝试用快排会出现什么样子的效果
归并排序,主要是一个递归过程,对左半部分和有半部分分别排序后进行合并的操作,但是这里是链表,所以采用两个指针,一个指针一次两步,一个一次一步,最后一个到达最后,一个在中间
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(!head||!head->next)
{
return head;
}
return Sort(head);
}
ListNode *Sort(ListNode *head)
{
if(!head||!head->next)
{
return head;
}
ListNode * lpoint = head;
ListNode * rpoint = head;
ListNode * pre = NULL;
while(rpoint&&rpoint->next)//<beacause each step rpoint move two position
{ //<rpoint is the last point or the NULL
rpoint = rpoint->next->next;
pre = lpoint;
lpoint = lpoint->next;
}
pre->next = NULL;
ListNode *lh = Sort(head);
ListNode *rh = Sort(lpoint);
return Merge(lh,rh);
}
ListNode *Merge(ListNode *lh,ListNode *rh)
{
ListNode *temp = new ListNode(0);
ListNode *result = temp;
while(rh && lh)
{
if(lh->val <= rh->val)
{
result->next = lh; //<there is no the type like result++
lh = lh->next;
result = result->next;
}
else
{
result->next = rh;
rh = rh->next;
result = result->next;
}
if(lh)
{
result->next = lh;
}
if(rh)
{
result->next = rh;
}
}
result = temp->next;
temp->next = NULL;
delete temp;
return result;
}
};
完整的测试程序
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
};
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(!head||!head->next)
{
return head;
}
return Sort(head);
}
ListNode *Sort(ListNode *head)
{
if(!head||!head->next)
{
return head;
}
ListNode * lpoint = head;
ListNode * rpoint = head;
ListNode * pre = NULL;
while(rpoint&&rpoint->next)//<beacause each step rpoint move two position
{ //<rpoint is the last point or the NULL
rpoint = rpoint->next->next;
pre = lpoint;
lpoint = lpoint->next;
}
pre->next = NULL;
ListNode *lh = Sort(head);
ListNode *rh = Sort(lpoint);
return Merge(lh,rh);
}
ListNode *Merge(ListNode *lh,ListNode *rh)
{
ListNode *temp = new ListNode;
temp->val = 0;
temp->next = NULL;
ListNode *result = temp;
while(rh && lh)
{
if(lh->val <= rh->val)
{
result->next = lh; //<there is no the type like result++
lh = lh->next;
result = result->next;
}
else
{
result->next = rh;
rh = rh->next;
result = result->next;
}
if(lh)
{
result->next = lh;
}
if(rh)
{
result->next = rh;
}
}
result = temp->next;
temp->next = NULL;
delete temp;
return result;
}
};
int main()
{
ListNode head[7];
for (int i = 0; i < 6; i++)
{
head[i].val = i+1;
head[i].next = &head[i+1];
}
head[2].val = 9;
head[4].val = 8;
head[6].val = 0;
head[6].next = NULL;
Solution cS;
ListNode * result = cS.sortList(head);
while (result)
{
cout<<result->val;
result = result->next;
}
return 0;
}