重新教自己学算法之递归排序——合并排序(五)

来源:互联网 发布:石金鑫知乎 编辑:程序博客网 时间:2024/05/30 23:09

前一篇中的快速排序和这次的合并排序都是经典的算法之一,区别在于:
快速排序:先分类在迭代
合并排序:先迭代在合并

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],另一边亦如此,数组有序。
总结:该排序是分治法的一个典型应用。

0 0
原创粉丝点击