归并排序续讲
先贴代码
long long count = 0;
int a[1000000 + 5];
int b[1000000 + 5];
void Merge(int sourceArr[], int tempArr[], int starIndex, int midIndex, int endIndex)
{
int i = starIndex;
int j = midIndex + 1;
int k = starIndex;
while (i != midIndex + 1 && j != endIndex + 1)
{
if (sourceArr[i] < sourceArr[j])
tempArr[k++] = sourceArr[i++];
else
{
tempArr[k++] = sourceArr[j++];
count += midIndex - i + 1;// *&*&*&*&*&*&*&*&*&
}
}
while (i != midIndex + 1)
tempArr[k++] = sourceArr[i++];
while (j != endIndex + 1)
tempArr[k++] = sourceArr[j++];
}
void Merge_sort(int sourceArr[], int tempArr[], int starIndex, int endIndex)
{
int midIndex;
if (starIndex < endIndex)
{
midIndex = (starIndex + endIndex) / 2;
Merge_sort(sourceArr, tempArr, starIndex, midIndex);
Merge_sort(sourceArr, tempArr, midIndex + 1, endIndex);
Merge(sourceArr, tempArr, starIndex, midIndex, endIndex);
}
}
上面的是标准的归并函数;
我们注意到在注释标记的地方加上了count来统计一个数值,这个数值代表的就是在排序中交换的总步骤。
下面是解释:
start\ 归并排序的过程实际是2个已经排好序的数列(A, B)进行合并(放入C数组)的过程,
在合并的过程中如果从A中选取数据,那么不计入步数统计,因为A数列默认在前,从前面选取数据不用交换
同理如果从B中拿数据就一定是从后面交换到前面的,也就是说一定经过了交换
如果是下面的直接放入C数组的元素是不用计入步数,因为在之前生成的时候就已经计入了步骤\end
对于解决交换次数 交换路径 等问题上文是一个时间复杂度为N log N的模板;
最后总代码
#include<stdio.h>
long long count = 0;
int a[1000000 + 5];
int b[1000000 + 5];
void Merge(int sourceArr[], int tempArr[], int starIndex, int midIndex, int endIndex)
{
int i = starIndex;
int j = midIndex + 1;
int k = starIndex;
while (i != midIndex + 1 && j != endIndex + 1)
{
if (sourceArr[i] < sourceArr[j])
tempArr[k++] = sourceArr[i++];
else
{
tempArr[k++] = sourceArr[j++];
count += midIndex - i + 1;
}
}
while (i != midIndex + 1)
tempArr[k++] = sourceArr[i++];
while (j != endIndex + 1)
tempArr[k++] = sourceArr[j++];
}
void Merge_sort(int sourceArr[], int tempArr[], int starIndex, int endIndex)
{
int midIndex;
if (starIndex < endIndex)
{
midIndex = (starIndex + endIndex) / 2;
Merge_sort(sourceArr, tempArr, starIndex, midIndex);
Merge_sort(sourceArr, tempArr, midIndex + 1, endIndex);
Merge(sourceArr, tempArr, starIndex, midIndex, endIndex);
}
}
int main(void)
{
int t, i, k, min, temp;
while (scanf_s("%d", &t) != EOF)
{
count = 0;
getchar();
for (i = 0; i < t; i++)
{
scanf_s("%d", &a[i]);
}
Merge_sort(a, b, 0, t - 1);
min = count;
for (k = 0; k < t - 1; k++)
{
count = 0;
a[k + t] = a[k];
Merge_sort(a, b, k + 1, k + t);
if (count < min)
min = count;
}
printf("%d\n", min + 1);
}
return 0;
}