插入排序和归并排序 [Algorithm]

插入排序:
template<typename T>
void insert_sort(T* ptr, int length)
{
	typedef T type;
	typedef type* ptr_type;

	type key;
	
	for (int i(1); i<length; i++)
	{
		key = ptr[i];

		int j = i-1;
		while (j>=0 && ptr[j]>key)
		{
			ptr[j+1] = ptr[j];
			j--;
		}
		
		ptr[j+1] = key;
	}
}
归并排序:
//
//	Test Case: merge(ptr, i, i, i+1);	
//	Test Case: merge(ptr, i, i, i);		
//
template<typename T>
void merge(T *ptr, int bg, int mid, int end)
{
	typedef T type;
	typedef type* ptr_type;

	//!	[使用哨兵位]
	//type imax = std::numeric_limits<type>::max();
	//int fsize = mid-bg+1;	//+1
	//ptr_type former = new type[fsize+1];
	//for (int i(0); i<fsize; i++)
	//	former[i] = ptr[bg+i];
	//former[fsize] = imax;
	//
	//int lsize = end-mid;	//end-mid-1 + 1
	//ptr_type latter = new type[lsize+1];
	//for (int i(0); i<lsize; i++)
	//	latter[i] = ptr[mid+1+i];
	//latter[lsize] = imax;

	//int fidx(0);
	//int lidx(0);
	//int aidx(bg);
	//while (aidx<=end)
	//{
	//	if (former[fidx] < latter[lidx])
	//		ptr[aidx] = former[fidx++];
	//	else
	//		ptr[aidx] = latter[lidx++];
	//	aidx++;
	//}
	//!	[使用哨兵位]

	//!	[不使用哨兵位]
	int fsize = mid-bg+1;	//+1
	ptr_type former = new type[fsize];
	for (int i(0); i<fsize; i++)
		former[i] = ptr[bg+i];

	int lsize = end-mid;	//end-mid-1 + 1
	ptr_type latter = new type[lsize];
	for (int i(0); i<lsize; i++)
		latter[i] = ptr[mid+1+i];

	int fidx(0);
	int lidx(0);
	int aidx(bg);
	while (aidx<=end)
	{
		if (fidx < fsize && lidx < lsize)
		{	
			if (former[fidx] < latter[lidx])
				ptr[aidx] = former[fidx++];
			else
				ptr[aidx] = latter[lidx++];
		}
		else if (lidx < lsize)
			ptr[aidx] = latter[lidx++];
		else
			ptr[aidx] = former[fidx++];

		aidx++;
	}
	//!	[不使用哨兵位]

	delete [] former; former = 0;
	delete [] latter; latter = 0;
}

template<typename T>
void merge_sort(T* ptr, int bg, int end)
{
	if (bg >= end)
		return;

	int mid = (bg+end)/2;

	merge_sort(ptr, bg, mid);
	merge_sort(ptr, mid+1, end);
	merge(ptr, bg, mid, end);
}
插入排序时间复杂度是n^2, 空间复杂度为1

 归并排序复杂度为nlgn,  空间复杂度为 n

在n较小的时候,插入排序较快, 当n较大的时候,归并排序优势异常明显,测试:

程序:

void test_insert_sort()
{
	const int test_num = 100000;	// 1 million
	srand((int)time(0));

	cout << "Test number " << "/t:/t/t" << test_num << std::endl;

	int* testPtr = new int[test_num];
	int* testPtr1 = new int[test_num];

	for(int idx=0; idx<test_num; idx++)
		testPtr1[idx] = testPtr[idx] = rand();

	clock_t t = clock();
	insert_sort(testPtr, test_num);
	cout << "Insert Sort " << "/t:/t/t" << clock() - t << std::endl;

	//for(int idx=0; idx<test_num; idx++)
	//	cout << testPtr[idx] << " ";
	//cout << endl;

	t = clock();
	merge_sort(testPtr1, 0, test_num-1);
	cout << "Merge Sort " << "/t:/t/t" << clock() - t << std::endl;

	//for(int idx=0; idx<test_num; idx++)
	//	cout << testPtr1[idx] << " ";
	//cout << endl;

	// Test the result validity 
	for(int idx=0; idx<test_num; idx++)
		assert(testPtr[idx]==testPtr1[idx]);

	delete[] testPtr;	testPtr = 0;
	delete[] testPtr1;	testPtr1 = 0;
}

 

结果:

// Test number     :               1000
// Insert Sort     :               1
// Merge Sort      :               4

// Test number     :               10000
// Insert Sort     :               109
// Merge Sort      :               27

// Test number     :               100000
// Insert Sort     :               11212
// Merge Sort      :               363

附录:

归并排序的变种,

逆序对,A[1, n] 数组中,如果i<j, A[i] > A[j]. 则 (i, j)为A中一个逆序对(inversion).

用nlgn最坏情况下,求n个元素任意排列中的逆序对数目:

//
//	用nlog(n)最坏时间,确定n个元素任意排列的逆序对数目
//
template<typename T>
int gather_compute(T *ptr, int bg, int mid, int end)
{
	typedef T type;
	typedef type* ptr_type;

	int ret_count = 0;

	int fsize = mid-bg+1;	//+1
	ptr_type former = new type[fsize];
	for (int i(0); i<fsize; i++)
		former[i] = ptr[bg+i];

	int lsize = end-mid;	//end-mid-1 + 1
	ptr_type latter = new type[lsize];
	for (int i(0); i<lsize; i++)
		latter[i] = ptr[mid+1+i];

	int fidx(0);
	int lidx(0);
	int aidx(bg);

	for (int i(0); i<fsize; i++)
		for (int k=0; k<lsize; k++)
			if (former[i]>latter[k])
				ret_count++;			

	while (aidx<=end)
	{
		if (fidx < fsize && lidx < lsize)
		{	
			if (former[fidx] < latter[lidx])
				ptr[aidx] = former[fidx++];
			else
				ptr[aidx] = latter[lidx++];
		}
		else if (lidx < lsize)
			ptr[aidx] = latter[lidx++];
		else
			ptr[aidx] = former[fidx++];

		aidx++;
	}

	delete [] former; former = 0;
	delete [] latter; latter = 0;

	return ret_count;
}

template<typename T>
int compute_reverse_pair(T* ptr, int bg, int end)
{
	if (bg >= end)
		return 0;

	int mid = (bg+end)/2;

	return compute_reverse_pair(ptr, bg, mid) +
			compute_reverse_pair(ptr, mid+1, end) +
			 gather_compute(ptr, bg, mid, end);
}


 

测试:

	{
		int test_data[] = {5,2,4,7,1,3,6};
		int length = sizeof(test_data) / sizeof(test_data[0]);

		cout << compute_reverse_pair(test_data, 0, length-1) << endl;
	}

http://blog.csdn.net/ryfdizuo/article/details/6057479

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值