归并排序是采用分治递归的思想来实现的,是一种有效的稳定的排序,其一般复杂度在O(nlogn)。
基本思想:将待排序的元素进行分组,将原来一个大的集合分成两个小的集合(这里就要采用分治递归的思想,子问题是独立的),再对小的集合进行排序,最终将已经排序好的小的集合进行合并,从而组成要求的排好序的集合。
void mergerarry(int *a, int x, int mid, int y, int *t)//x代表此时集合的首元素的位置,y代表此时集合的末元素的位置
{
int m = mid, n = y;
int i = x, j = mid + 1;
int k = 0;
while(i <= m && j <= n)//判读哪个子集的首元素比较小,放入t中,直到一个集合为空
{
if(a[i] <= a[j])
t[k++] = a[i++];
else
t[k++] = a[j++];
}
//如果其中一个集合非空,则要将剩余的元素放入t中,此时非空集合的首元素肯定会比放进去的大
while(i <= m)
t[k++] = a[i++];
while(j <= n)
t[k++] = a[j++];
for(i = 0; i < k; i++)//经t中排好序的元素重新输入a中,保证接下来的更大一点的子集的排序
a[x + i] = t[i];
return ;
}
void merger_sort(int *a, int x, int y, int *t)
{
if(y > x)
{
int mid = (x + y) / 2;
//采用二分的思想
merger_sort(a, x, mid, t);
merger_sort(a, mid + 1, y, t);
mergerarry(a, x, mid, y, t);
}
return ;
}
归并排序的好处就在与其不依赖于输入数组中元素的组合方式,避免了快速排序的中最糟糕的情况,当然,在一些情况下,归并排序不比快速排序更快,归并排序要是用额外的数组来帮助,付出了一些空间代价,可以算是归并排序的缺点。