(学习4)二分归并排序

二分归并排序也称归并排序

  首先附上帮助高效我理解的博客: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\n",num[i]);
    }
    
    return 0;
}
View Code

 时间复杂度:nlog(n);

目前先写这么多....,以后可能还要完善...

猜你喜欢

转载自www.cnblogs.com/pipihoudewo/p/12513024.html
今日推荐