二分归并排序也称归并排序
首先附上帮助高效我理解的博客:https://www.jianshu.com/p/33cffa1ce613
算法介绍:采用分治的思想,即将大问题转换为小问题,但是它们的前提一定要一样,否则就是两个问题了。归并排序即对一个序列进行一分为二,然后对两个子序列再进行一分为二,直到子列只有一个数,则返回,通过不断将子序列两两归并,最后将整个大序列归并排好序。
因为我采取归并的方式,所以可以想象原来一个待排序的序列,先一分为二,但是这两个序列中不止一个元素,所以我们要继续一分为二,....直到一分为二后的序列只有一个元素,这时候我们可能已经向下递归很多层啦,接下来如果子序列只有一个元素我们就默认为有序的啦(也没得和别的数字排呀!),然后这时候我们就可以返回上一级序列了(即有两个元素的子序列),然后对这个子序列进行归并(过程见代码),然后又上一级归并,...通过不断的归并,我们最后就能达到归并最初一分为二的两个序列啦!归并完这两个序列就大功告成~
下面给代码
// // main.c // 作业4 // // Created by yizhihenpidehou on 2020/3/17. // Copyright © 2020 yizhihenpidehou. All rights reserved. // #include <stdio.h> #define maxen 30 void merge(int arr[],int l,int r){ int mid=(l+r)/2; int tmp[maxen]; int x1=l; int x2=mid+1; int i=0; while(x1<=mid&&x2<=r){ //对子列进行归并 tmp[i++]=arr[x1]<arr[x2]?arr[x1++]:arr[x2++]; } while(x1<=mid){//将剩余的放入tmp tmp[i++]=arr[x1++]; } while(x2<=r){ //将剩余的放入tmp tmp[i++]=arr[x2++]; } for(int j=0;j<(r-l+1);j++){ arr[j+l]=tmp[j]; //将tmp已经归并好的子序列放到arr中 } } void merge_sort(int arr[],int l,int r){ // 归并排序 if(l==r){ return ; } int mid=(l+r)/2; merge_sort(arr, l, mid); merge_sort(arr,mid+1, r); merge(arr,l,r); } int main(void) { int num[maxen]={0,2,3,6,8,1,4,5,7}; merge_sort(num, 1, 8); for(int i=1;i<=8;i++){ printf("%d ",num[i]); } return 0; }
时间复杂度:nlog(n);
分析与推导(直接上图)
复杂度
目前先写这么多....,以后可能还要完善...