归并排序法和基数排序法

Posted jeavenwong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了归并排序法和基数排序法相关的知识,希望对你有一定的参考价值。

归并排序法,这里介绍二路归并排序法,其他原理类似,只是更加复杂。

归并排序(Merge Sort)是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。

归并排序的具体做法:

  1. 把原序列不断地递归等分,直至每等份只有一个元素,此时每等份都是有序的。
  2. 相邻等份合并,不断合并,直至合并完全。

二路归并

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序最常用的是二路归并,即把两个小的有序的序列和并成一个大的有序序列:合二为一。

一个二路归并的流程图是这样的:

技术分享图片

多路归并无非是多个有序的小序列合并成一个大的有序序列,道理和二路归并一样。

 

把两个有序序列合成一个大的有序序列的实现代码如下:

void MergeSort(int* a,int* b,int na,int nb,int* c)
{
    if(a == NULL || na <= 0 || b == NULL || nb <= 0)
        return;
    int i=0,j=0,k=0;
    //将a和b数组中的元素有序的放入到c数组中
    while(i<na && j<na)
    {
        if(a[i]<=b[j])
            c[k++] = a[i++];
        else
            c[k++] = b[j++];
    }
    
    //将剩下的元素全都放入到c数组中
    while(i<na)
        c[k++] = a[i++];
    while(i<nb)
        c[k++] = b[j++];
    
}

 

可以看出,二路归并的时间复杂度是O(n),n是原序列的数据规模。以上代码是归并排序的基础,弄懂了它,就很好写归并排序了,看下归并排序的流程图:

技术分享图片

可以看出,上半部分不断地递归深入:不断地均分原序列,直到每一部分只含有一个元素。下半部分,开始递归返回,通过反复调用二路归并算法,把相邻的有序子序列合并成一个规模更大的序列。

归并排序的代码如下:

//把[first,mid]与[mid+1,last]范围内的数据合并
void mergeArray(int* a,int* b,int first,int mid,int last)
{
    int i = first;
    int j = mid + 1;
    int k = 0;
    while(i<=mid && j<=last)
    {
        //将[first,mid]与[mid+1,last]内的数据排序合并
        while(i<=mid && a[i]<=a[j])
            b[k++] = a[i++];
        while(j<=last && a[j]<a[i])
            b[k++] = a[j++];
        
        //将剩下的a的数组元素放入到b中
        while(i<=mid)
            b[k++] = a[i++];
        while(j<=last)
            b[k++] = a[j++];
    }
    //将合并后的数组返回到a数组上
    for(int i=0;i<k;i++)
        a[first+i] = b[i];
    
}

//归并排序
void mergesort(int* a,int* b,int first,int last)
{
    if(first < last)
    {
        int mid = first + (last-first)>>1; //求区间中点
        //不断的划分区间,然后进行递归操作
        mergesort(a,b,first,mid); 
        mergesort(a,b,mid+1,last);
        mergeArray(a,b,first,mid,last);
    }
}

//传入需要归并排序的数组
void MergeSort(int* a,int n) 
{
    if(a == NULL && n <= 1)
        return;
    int b[n];
    mergesort(a,b,0,n-1); 
    delete[] b;
}

 

归并排序参考:http://blog.csdn.net/zhangxiangdavaid/article/details/34463409

 

 

基数排序法

今天看了太多排序,累了,晚点更新。。。

 

以上是关于归并排序法和基数排序法的主要内容,如果未能解决你的问题,请参考以下文章

基础排序算法总结(代码+图片分析)

java常用八大排序法

有啥算法是相邻交换排序的(除了冒泡以外)

数据结构学习笔记——基数排序和排序算法总结

C# 各种内部排序方法的实现(直接插入排序希尔排序冒泡排序快速排序直接选择排序堆排序归并排序基数排序)

C# 各种内部排序方法的实现(直接插入排序希尔排序冒泡排序快速排序直接选择排序堆排序归并排序基数排序)