归并排序的递归实现(自顶向下)以及迭代法(自底向上)

写完了时间复杂度O(n^2)的几大经典排序算法,接下来开始写时间复杂度O(nlogn)的排序算法
这篇文章先介绍归并排序的递归实现以及迭代实现

1.概念

归并排序采用分治的思想,将一组无序的数据平均分为多个小块,分到极限时,每一块仅包含1个数据,此时每块都是有序的。接下来进行归并操作。下图为维基百科gif图
在这里插入图片描述

2.递归实现

template<typename T>
void __merge(T arr[],int l,int middle,int r){
    T temp[r-l+1];
    int k=0;
    int i = l;
    int j = middle+1;

    //下标正确范围内 进行排序
    while(i<=middle && j<=r){
        temp[k++] = arr[i]<=arr[j]?arr[i++]:arr[j++];
    }

    //退出while循环 存在下标越界
    while(i<=middle){
        temp[k++]=arr[i++];
    }
    while(j<=r){
        temp[k++]=arr[j++];
    }

    for(int i=0;i<r-l+1;i++){
        arr[i+l] = temp[i];
    }
}

template<typename T>
void __mergeSort(T arr[],int l,int r){
     if(r-l<=15){               //基于插入排序的特性进行小优化(包括快速排序中也可以使用此优化)
        insertionSort(arr,l,r);//对于归并过程,当剩余未排序元素越少时,这些元素的有序性越高,
        return ;			  //对于插入排序而言,时间复杂度进化到O(n)级别  
    } 
    int middle = (l+r)/2;
    __mergeSort(arr,l,middle);
    __mergeSort(arr,middle+1,r);

    if(arr[middle]>arr[middle+1]) //此处是比较大的优化
        __merge(arr,l,middle,r); //举例:1 2 和 3 4 两组数据进行归并 两组数据各自都是有序的
   								//此时因为2<3 所以 1234已经有序 无需进行merge操作 		
 }

template<typename T>
void mergeSort(T arr[],int n){
    __mergeSort(arr,0,n-1);
}

3.迭代实现(自底向上)

//自底向上 非递归算法
template<typename T>
void mergeSortBU(T arr[],int n){
    for(int size=1;size<=n;size*=2){
        for(int i=0;i+size<n;i+=2*size){
            __merge(arr,i,i+size-1,min(i+2*size-1,n-1));
        }
    }
}

4.性能测试

测试样本n=50000 range:0~50000的随机整数数组和完全有序数组
在这里插入图片描述

下文介绍基于归并排序实现一些相关的算法

发布了16 篇原创文章 · 获赞 1 · 访问量 1733

猜你喜欢

转载自blog.csdn.net/qq_42584241/article/details/104699484
今日推荐