O(nlogn)时间复杂度 链表排序

可以使用归并排序

int counter = 0;// statistic

struct list_node
{
	int val;
	struct list_node* next;
	list_node(int t, struct list_node* pn = 0)
	{
		val = t;
		next = pn;
	}
};

typedef list_node* list;

void insert_list(list& h, int t)
{
	if (0 == h)
	{
		h = new list_node(t);
		return;
	}

	list pn = new list_node(t, h);
	h = pn;
}

// find the middle node of the list
list find_mid(list h)
{
	list pn = h;
	if (0 == pn->next || 0 == pn) return pn;
	while(h != 0 && h->next != 0)// && h->next->next != 0) // it is needless
	{
		pn = pn->next;
		h = h->next->next;
	}
	return pn;
}

list merge_list(list h1, list h2)
{
	list hret = (0 != h1) ? h1:h2;// head of the returned list
	if (0 == hret) return hret;
	
	hret = (h1->val < h2->val) ? h1:h2;
	if (hret == h1)
		h1 = h1->next;
	else 
		h2 = h2->next;

	list ret = hret; // the last node of the returned list
	while( (0 != h1) && (0 != h2) )
	{
		counter ++;// no usage, just for statistic
		if (h1->val < h2->val)
		{
			ret->next = h1;
			ret = h1;// reassign ret
			h1 = h1->next;
		}
		else
		{
			ret->next = h2;
			ret = h2;// reassign ret
			h2 = h2->next;
		}
	}

	// attach the remained nodes to the ret list
	if (0 != h1)	ret->next = h1;
	else if(0 != h2)	ret->next = h2;
	else ret->next = 0; // 0 is the end of the returned list

	return hret;
}

list merge_sort_list(list h)
{
	if (0==h ||0==h->next) return h;
	
	list mid1 = find_mid(h);
	if (0 == mid1) return 0;

	list mid = mid1->next;
	mid1->next = 0;// break up the list h into h and mid

	list h1 = merge_sort_list(h);
	list h2 = merge_sort_list(mid);

	counter++;// no usage, just for statistic
	return merge_list(h1, h2);
}

int main(int argc, char* argv[])
{
	list h = 0;// necessary to initialize, else h1 equal to 0xcccccccc
	for (int i=0 ;i< 4096; ++i)
		insert_list(h, rand()%100000);

	list ret = merge_sort_list(h);
	cout<<counter<<endl;// show how many operations
	while(0 != ret)
	{
		cout<<ret->val<<endl;
		ret = ret->next;
	}
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值