归并排序,递归实现和迭代实现

归并排序:

时间复杂度O(nlogn)

空间复杂度O(n+logn)

比较占用内存,但却效率高且稳定的方法

#define MAX_SIZE 55
int num[] = {2,3,4,5,3,2,4,52,2};
int len = 9;
int* tr2 = new int[MAX_SIZE];

void mergeSort(int num, int len)
// 递归实现版本
{
	mSort(num, num, 0, len-1);
}
void mSort(int* sr, int* tr2, int low, int high)
{
	if(low == high)
		tr[low] = sr[low];
	else
	{
		int m = (low + high) / 2;
		mSort(sr, tr2, low, m);
		mSort(sr, tr2, m+1, high);
		Merge(tr2, tr1, low, m, high);
	}
}
void Merge(int* sr, int* tr, int low, int m, int high)
{
	for(int i = low, j = m+1; low <= m && j <= high; i++)
	{
		if(sr[low] > sr[j])
			tr[i] = sr[low++];
		else
			tr[i] = sr[j++];
	}
	if(low <= m)
		for(int k = 0; k <= m - low; k++)
			tr[i+k] = sr[low+k];
	if(j <= high)
		for(int k = 0; k <= high - j; k++)
			tr[i+k] = sr[j+k];
}


void mergeSort(int* num, int len)
//迭代实现版本
{
	int* tr = (int*)malloc(len*sizeof(int));
	int k = 1; //初始步长设为1
	while(k < len-1)
	{
		MergePass(num, tr, k, len-1);
		k = k * 2;
		MergePass(tr, num, k, len-1);
		k = k * 2;
	}
}
void MergePass(int num, int tr, int k, int len)
{
	int i = 0; // 从队首开始
	int j;
	while(i <= len-2*k+1)
	{
		Merge(sr, tr, i, i+k-1, i+2*k-1);
		i = i + 2*k;
	}
	if(i < n-k+1) // *****归并最后两个序列,
		Merge(sr, tr, i, i+k-1, len);
	else
		for(j = i; j <= len; j++)
			tr[j] = num[j];
}

对注释中**的讲解:

这里需要注意两个位置,len-k+1 和 len-2*k+1

7

8

9

10

11

12

假设现在已经到了这种情况,

K = 3;

Len = 12;

Len – k + 1 = 10;

Len – 2 * k + 1 = 7;

 

  • 如果此时i的值刚好位于7,恰好可以最后一次 while 循环
  • 如果i的值位于7和10之间,说明此时不能够用 while 循环里的合并(i+2*k-1)会越界

        就需要添加一个额外的归并最后一个序列

 

  • 如果i的值位于10之后,说明不能当做序列合并了(此时不够一个序列的长度),直接 tr[j++] = num[j++];

 

 

 

你可能感兴趣的:(4_20)