Linklist O(nlogn) sort

O(nlogn)属于性能较优的排序算法,但是用在链表确实要注意很多,它不支持高效的随机访问,所以需要用在qsort这种,估计达不到O(logn)  这时突然想起来其实还是可以用

lumoto版的partition来qsort的,后面再试试看。堆排序几乎不可行,因为堆得调整不断的随机访问,链表效率极低,当时我只想到mergesort,

然后非递归版的太繁琐,我也不愿去看了,于是想可以非递归么,算了下时间复杂度,在mid=(low+high)/2这一步比之前加了O(n), 所以T(n)=2T(n/2)+2n, plug-in算出来是T(n)=n+2nlogn=O(nlogn)符合要求,于是开搞,就是要加个尾指针比较刮三,但是也还好。另外我觉得还是把copy放到Merge这一步结构比较清晰,改成其他要求的也比较容易。


里面就是算mid指针,比较纠结点,while(i<(length-1)/2) 还稍微倒腾了一下把奇偶统一起来,里面copy的时候我是直接copy到数组,然后再copy回linklist,这样不用在new新的堆空间了,提交挺顺利,直接AC了。

另外测试用了尾插法,也是始终记录尾指针,回来发现google几乎所有服务都不能用了,包括leetcode之前都gplus登陆的,换了host,改了实验协议也还是不行。。。。

于是只能蛋疼的重新注册一个账号。。。


代码:

#include <iostream>
using namespace std;

struct ListNode{
	int val;
	ListNode* next;
};
void Merge(ListNode* low, ListNode* mid, ListNode* high, int length);
ListNode* MergeSort(ListNode* low, ListNode* high);
ListNode *sortList(ListNode *head)
{
	if(head==NULL||head->next==NULL) return head;

	ListNode*p=head;
	while(p->next!=NULL)
		p=p->next;
	return MergeSort(head,p);
}
ListNode* MergeSort(ListNode* low, ListNode* high)
{
	if(low==high) return low;
	else
	{
		//get length
		int length=1;
		ListNode* p=low;
		while(p!=high)
		{
			length++;
			p=p->next;
		}
		
		//get mid point
		p=low;
		int i=0;
		while(i<(length-1)/2)
		{
			p=p->next;
			i++;
		}
		
		//recursively merge two part
		MergeSort(low,p);
		MergeSort(p->next,high);
		
		//merge two parts to one
		Merge(low,p,high,length);
		//Copy(low,a);
		return low;
	}
	
}
void Merge(ListNode* low, ListNode* mid, ListNode* high, int length)
{
	ListNode* p1=low,*p2=mid->next;
	int *a=new int[length];
	int i=0;
	while(p1!=mid->next&&p2!=high->next)
	{
		if(p1->val < p2->val)
		{
			a[i]=p1->val;
			p1=p1->next;
		}
		else
		{
			a[i]=p2->val;
			p2=p2->next;
		}
		i++;
	}
	if(p1==mid->next)
	{
		while(p2!=high->next)
		{
			a[i]=p2->val;
			p2=p2->next;
			i++;
		}
	}
	else if(p2==high->next)
	{
		while(p1!=mid->next)
		{
			a[i]=p1->val;
			p1=p1->next;
			i++;
		}
	}
	ListNode* q=low;
	for(int i=0;i<length;i++)
	{
		q->val=a[i];
		q=q->next;
	}

	delete []a;
}
ListNode* CreateLinkList(int* data, ListNode*& rail1, int n)  
{  
    ListNode* head=NULL;  
    head=new ListNode();  
    head->val=data[0];  
    head->next=NULL;  
    ListNode* rail=head;// record each rail  
    for(int i=1;i<n;i++)  
    {  
        ListNode* p=new ListNode();  
        p->val=data[i];  
        p->next=NULL;  
        rail->next=p;  
        rail=rail->next;  
    }  
	rail1=rail;
    return head;  
}
void ShowList(ListNode* head)
{
	while(head!=NULL)
	{
		cout<<head->val<<" ";
		head=head->next;
	}
	cout<<endl;
	return ;
}
int main()
{
	int a[]={3,2,1,324,634,23};
	ListNode* rail=NULL;
	ListNode* head=CreateLinkList(a,rail,6);
	ShowList(head);
	//MergeSort(head,rail);
	head=sortList(head);
	ShowList(head);

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值