合并排序

#合并排序#
合并排序通过把一个数组不断地分解成一个一个更小的数组,最终得到一个长度为1的数组,对同级的长度为1的数组进行合并,得到一个排好序的长度为2的小数组,然后与其同级的另外一个长度为2的数组进行合并,以此类推,最终得到一个排好序的数组,其源代码如下

void Sort::mergeSortDescend(int l, int r)
{
	//if l< r, the array has been divided to the smallest array
	if (l != r)
	{
		int m = floor((float)(l + r) / 2);
		mergeSortDescend(l, m);
		mergeSortDescend(m+1, r);
		mergeDescend(l, m, r);
		//mergeAscend(l, m, r);
	}
}

void Sort::mergeDescend(int l, int m, int r)
{
	//the length of left array
	int len1 = m - l + 1;
	//the length of right array
	int len2 = r - m;
	//the small array, its length is len1 + 1, because we need the last integer to be a canary
	int *left = new int[len1 + 1];
	int *right = new int[len2 + 1];
	//the last integer was set to the minium number
	left[len1] = -1;
	right[len2] = -1;
	//copy the left subarray
	for (int i = 0; i < len1; i++)
	{
		left[i] = a[l + i];
	}
	//copy the right subarray
	for (int i = 0; i < len2; i++)
	{
		right[i] = a[m + i + 1];
	}
	//the counter in the left and right array
	int i = 0;
	int j = 0;
	cout << "Sorting:";
	for (int k = l; k <= r; k++)
	{
		//compare the present integer in left subarray and that in right subarray
		//set the present array integer to the bigger one
		if (left[i] > right[j])
		{
			a[k] = left[i];
			i++;
		}
		else
		{
			a[k] = right[j];
			j++;
		}
		cout << a[k] << " ";
	}
	cout << endl;
	//delete the new arrays
	delete []left;
	delete []right;
}
void Sort::mergeSortAscend(int l, int r) {
	//if l< r, the array has been divided to the smallest array
	if (l != r)
	{
		int m = floor((float)(l + r) / 2);
		mergeSortAscend(l, m);
		mergeSortAscend(m + 1, r);
		mergeAscend(l, m, r);
		//mergeAscend(l, m, r);
	}
}

void Sort::mergeAscend(int l, int m, int r)
{
	//the length of left array
	int len1 = m - l + 1;
	//the length of right array
	int len2 = r - m;
	int *left = new int[len1 + 1];
	int *right = new int[len2 + 1];
	left[len1] = 1000000;
	right[len2] = 1000000; 
	cout << "Sorting: ";
	for (int i = 0; i < len1; i++)
	{
		left[i] = a[l + i];
	}
	for (int i = 0; i < len2; i++)
	{
		right[i] = a[m + i + 1];
	}
	int i = 0;
	int j = 0;
	for (int k = l; k <= r; k++)
	{
		if (left[i] < right[j])
		{
			a[k] = left[i];
			i++;
		}
		else
		{
			a[k] = right[j];
			j++;
		}
		cout << a[k] << " ";
	}
	cout << endl;
	delete []left;
	delete []right;
}

首先我们在mergeSort函数里面接受了两个参数(要排序的数组定义和其初始化放在了类的私有变量里面),这两个参数分别是排序数组的区间,l代表左边界,r代表右边界,通过递归调用本身, mergeSort完成了对待排序数组的划分,最后通过调用merge函数不断向上回溯,从左到右的对数组进行合并,由于子数组如果有一方被遍历完了,接下来将会继续比较下一个数,因此把子数组的最后一位作为哨兵,哨兵不会被纳入数组中,但是它能够完成控制子数组的边界工作,根据排序的方向,可以把哨兵设置为一个很小的值(降序排列)或者是很大的值(升序排列)。

复杂度分析
每次调用merge函数将会花费 θ ( n ) \theta(n) θ(n)的时间,其中 n = r − l + 1 n = r-l+1 n=rl+1, 每次递归将会得到一个 T ( n / 2 ) T(n/2) T(n/2)的时间复杂度,即合并排序的时间复杂度为:
T ( n ) = { c , n = 1 2 T ( n / 2 ) + c n , n > 1 T(n) = \begin{cases} c & ,n = 1\\ 2T(n/2) + cn & ,n > 1\end{cases} T(n)={c2T(n/2)+cn,n=1,n>1
根据主定理
T ( n ) = a T ( n / b ) + f ( n ) T(n) = aT(n/b) + f(n) T(n)=aT(n/b)+f(n)
由于 log ⁡ b a = 1 \log_ba = 1 logba=1, f ( n ) = c n = θ ( n ( log ⁡ b a ) ) = θ ( n ) f(n) = cn = \theta(n^{(\log_ba)}) = \theta(n) f(n)=cn=θ(n(logba))=θ(n), 所以合并排序的时间复杂度为 θ ( n l g n ) \theta(nlgn) θ(nlgn)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值