前一篇中的快速排序和这次的合并排序都是经典的算法之一,区别在于:
快速排序:先分类在迭代
合并排序:先迭代在合并
void _merge_array(int array[], int first, int middle,int last, int temp[])
{
int i = first, j = middle + 1; //将数组a分成两部分
int m = middle, l = last;
int k = 0;
while(i <= m && j <= l)
{
if(array[i] <= array[j])
{
temp[k] = array[i];
i++;
k++;
}
else
{
temp[k] = array[j];
j++;
k++;
}
}
while(i <= m)
{
temp[k] = array[i];
i++;
k++;
}
while(j <= l)
{
temp[k] = array[j];
j++;
k++;
}
for (int i = 0; i < k; ++i)
{
array[first + i] = temp[i];
}
}
void merge_array(int array[], int first, int last, int temp[])
{
if(first < last)
{
int middle = (first + last) / 2;
merge_array(array, first, middle, temp); //左边有序
merge_array(array, middle + 1, last, temp); //右边有序(到递归到只剩两个数,每组一个,自然有序)
_merge_array(array, first, middle, last, temp);
}
}
先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。
解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?
可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。
举个例子,[2,1,5,4,8,3,9,7],分成[2154],[8397],再分成[21],[5,4];
[8,3],[9,7]; 再分[2],[1],[5],[4],[8],[3],[9],[7].只剩一个数数据时,有序。
合并[1,2],[4,5],,,在合并[1,2,4,5],另一边亦如此,数组有序。
总结:该排序是分治法的一个典型应用。