归并排序

来源:互联网 发布:python编程(第四版) 编辑:程序博客网 时间:2024/05/17 08:40

归并排序是通过递归实现分治的。主要的思想就是把一个大的序列不断的细分成小的序列,然后对这些小的序列进行排序,之后将这些小的序列不断的归并,形成有序的大的序列。

代码如下:

#include <iostream>using namespace std;void Print(int len, int *array){int i = 0;for(i = 0; i < len; ++i){cout << array[i] << " ";}}void CopyArray(int len, int *newArray, int *oldArray){    int i = 0;    for(i = 0; i < len ; ++i)    {        newArray[i] = oldArray[i];    }}//归并两个子序列void Merge(int pre, int mid, int post, int array[]){    const int L = mid - pre + 1;//L表示左边序列的元素个数    const int R = post - mid;//R表示右边序列的元素个数    int *LArray = new int[L];    int *RArray = new int[R];    //复制左边的序列    CopyArray(L, LArray, array + pre);//Print(L, LArray);//复制右边的序列    CopyArray(R, RArray, array + mid + 1);//Print(R, RArray);    int i = 0;    int j = 0;int k = pre;    for(; ; )    {        //如果某一个(左边或者右边)子序列到了边界,就跳出循环        if(i >= L || j >= R)        {            break;        }        else        {            if(LArray[i] > RArray[j])            {                array[k] = RArray[j];                ++j;                ++k;            }            else            {                array[k] = LArray[i];                ++i;                ++k;            }        }    }    //接下来的两个循环是判断有没有剩下的没有归并的子序列,有的话,直接拼接上去。    for(; i < L; ++i)    {        array[k] = LArray[i];        ++k;    }    for(; j < R; ++j)    {        array[k] = RArray[j];        ++k;    }delete[] LArray;delete[] RArray;}//把一个序列递归分成子序列void MergeSort(int pre, int post, int array[]){    //pre代表数组首元素的下标,post代表数组最后一个元素的下标    if(post - pre <= 0)    {        //如果当前的序列只有一个元素,则跳出,不移动其位置。        return ;    }    else    {int mid = (pre + post) / 2;//向下取整,        MergeSort(pre, mid, array);//把左边的序列继续细分        MergeSort(mid + 1, post, array);//把右边的序列继续细分        Merge(pre, mid, post, array);//调用归并函数,将排好序的两个子序列归并成一个序列    }}int main(){    int array[10] = {2, 4, 5, 1, 7, 9, 11, 24, 17, 12};//检测归并排序是否正确。    MergeSort(0, 10 - 1, array);    int i = 0;    for(i = 0; i < 10; ++i)    {        cout << array[i] << " ";    }    cout << endl;//system("PAUSE");    return 0;}

可以把归并看成一个树形的递归,每次都会把一个较大的序列分成两部分,进而,形成一个2元树。然后在每个分支点调用Merge函数对子序列进行归并。



例如,对于序列{2, 4, 5, 1}



在归并排序中拥到了分治的思想。归并排序也比插入排序快,时间复杂度是(N lgN)。

0 0
原创粉丝点击