算法介绍:采用分治的思想,即将大问题转换为小问题,但是它们的前提一定要一样,否则就是两个问题了。归并排序即对一个序列进行一分为二,然后对两个子序列再进行一分为二,直到子列只有一个数,则返回,通过不断将子序列两两归并,最后将整个大序列归并排好序。
因为我采取归并的方式,所以可以想象原来一个待排序的序列,先一分为二,但是这两个序列中不止一个元素,所以我们要继续一分为二,…直到一分为二后的序列只有一个元素,这时候我们可能已经向下递归很多层啦,接下来如果子序列只有一个元素我们就默认为有序的啦(也没得和别的数字排呀!),然后这时候我们就可以返回上一级序列了(即有两个元素的子序列),然后对这个子序列进行归并(过程见代码),然后又上一级归并,…通过不断的归并,我们最后就能达到归并最初一分为二的两个序列啦!归并完这两个序列就大功告成~
//
// 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;
}