算法之旅——归并排序

 归并排序是将两个或两个以上有序子序列归并成一个有序数列的排序的排序算法,其时间复杂度O(n*log n)仅次于高速排序。在内排序中,通常採用的是2-路归并,即每两个子序列为一组进行排序。

归并排序的原理是:设初始序列含有N个记录,则能够看成N个有序的子列,每一个子序列的长度为1。然后两两归并。得到N/2个长度为2或1的子序列。再两两归并,如此反复的归并下去。直到到达一个有序的序列为止。

设初始数组为:49,38,65,97,76,13,27。

则归并步骤例如以下

归并排序的思想简要介绍例如以下:对2个有序的子数组,开辟一个大小为两数组长度的新数据,先比較两子数据的首元素。将小者存入新数组。同一时候新数组和存数的那个数组后移一位。继续比較,若某个数组的元素都比較完了。则将为比較完的数组的元素一次填入新数组。

归并排序最好。最坏及平均时间复杂度皆为O(n*log n),可见其效率是非常高的。可是它的空间复杂度O(n),这也是用空间换时间的缘故,算法中,空间复杂度和时间复杂度是一对矛盾体。我们须要找出它们的平衡点。才干设计出高效的算法。归并排序也是高效排序算法中唯一稳定的算法(稳定性是指最坏情况下时间复杂度和最好情况下时间复杂度。若同样则稳定,若不同则不稳定)

归并排序多用于外排序中,这里的“外”是指外存,多数情况是硬盘。它可用于较大数据量的排序,通常将大数据量切割成若干个小数据量,然后用高速排序或其它算法对小数据量进行排序,。这几块小数据量排完序后。再对其归并排序,这样就对整个大数据量完毕了排序。

归并排序參考代码例如以下:

//description:归并排序
//author:hust_luojun
//date:2014_7_23

#include <iostream>

using namespace std;

int main()
{
    void merge_sort(int a[], int b[],int,int);
    int a[]={3,6,18,25,28};
    int b[]={4,8,12,20,26,30,56};
    int length_a=sizeof(a)/sizeof(int);  //求数组元素个数
    int length_b=sizeof(b)/sizeof(int);
    cout<<"arrary a:"<<endl;
    for(int i=0;i<length_a;i++)
        cout<<a[i]<<"  ";
    cout<<endl;
    cout<<"arrary b:"<<endl;
    for(int j=0;j<length_b;j++)
        cout<<b[j]<<"  ";
    cout<<endl;
    merge_sort(a,b,length_a,length_b);
    return 0;
}

void merge_sort(int a[],int b[],int length_a,int length_b)
{
    int length_c=length_a+length_b;
    int c[length_c];
    int i=0;
    int j=0;
    int k=0;

    while(i<length_a&&j<length_b)
    {
        if(a[i]<=b[j])          //逐位比較两数组元素,将小者存入c数组,然后移位
           c[k++]=a[i++];
        else
           c[k++]=b[j++];
    }

    while(j<length_b)   //i已指向a数组末尾。将b数组剩下的元素填入c数组
        c[k++]=b[j++];
    while(i<length_a)   //j已指向b数组末尾,将a数组剩下的元素填入c数组
        c[k++]=a[i++];
    cout<<"the sorted numbers are:"<<endl;
    for(k=0;k<length_c;k++)
        cout<<c[k]<<"  ";
}

程序执行结果为:


posted @ 2016-01-27 14:53  mengfanrong  阅读(192)  评论(0编辑  收藏  举报