归并排序 MergingSort
平均、最好、最坏:O(nlogn)
辅助空间:O(n) 申请了空间
最大的特点:稳定的改进算法
归并排序:强调要马跑得快,就得给马吃个饱,哈哈
算法思想:假设初始序列含有n个记录,则可以堪称n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n / 2]个长度为2或者1的有序子序列;再两两归并,重复,直到得到一个长度为n的有序序列为止。这是2路归并排序。分治法的典型应用。
简单来说,就是先划分子表,再合并半子表
代码如下,C++,采用递归解决方案:
// 将有序的a[start..mid]和a[mid+1..end]归并为有序的t[start..end]
void merge(int *a, int *t, int start, int mid, int end)
{
int i, j, k;
for(i=mid+1,j=start; start<=mid && i<=end; ++j)
{
if(a[start] < a[i])
t[j] = a[start++];
else
t[j] = a[i++];
}
if(start <= mid)
{
for(k=0; k<= mid-start; ++k)
t[j+k] = a[start+k];
}
if(i <= end)
{
for(k=0; k<=end-i; ++k)
t[j+k] = a[i+k];
}
}
//归并排序 a为待排数组,t为目标数组
void merge_sort(int *a, int *t, int startIndex, int endIndex)
{
int mid;
int temp[100] = {0};
if(startIndex == endIndex)
{
t[startIndex] = a[startIndex];
} else
{
mid = (startIndex + endIndex) / 2;
merge_sort(a, temp, startIndex, mid);
merge_sort(a, temp, mid+1, endIndex);
merge(temp, t, startIndex, mid, endIndex);
}
}
int a[Num];
for(int i=0; i<Num; i++)
{
a[i] = rand()%100 + 1;
}
int length = sizeof(a)/sizeof(*a);
//归并排序
int b[Num];
merge_sort(a, b, 0, length-1);