假如给你一个数组int a[9]={9,7,1,3,8,2,5,4,6};那么使用归并排序就是先把他拆成长度9为一的数组然后在比较在合成流程图类似于这种:
在网上看了半天原理是懂了,但是具体过程怎么回事?尤其是递归那里,网上很多直接就说拆完左边拆右边。说的很好,那么我也可以说我的身高不到10米。于是乎我单独把递归那里拿出来运行并打了标记。
void fen(int num[],int left,int right,int flage){
if(flage==0){
printf("%d\n",1);
}else if(flage==1){
printf("%d\n",2);
}else if(flage==2){
printf("%d\n",3);
}
printf("%d%d\n",num[left],num[right]);
if(left<right){
int mid=(left+right)/2;
printf("%d%dmid=%d\n",left,right,mid);
fen(num,left,mid,1);
fen(num,mid+1,right,2);
paixu(num,left,right,mid);
//merge(num,left,mid,right);
// printf("%d\n",555);
}
在两个递归中加了flage运行哪个递归就很容易知道了
2代表fen(num,left,mid,1);运行,3代表paixu(num,left,right,mid);运行,可以得出下图红色为运行顺序。
一直先分左边,分到不能再分了再回来分右边,如9 7 1 3 8那里,971是左边,分完之后回来分38(右边),38又可以分左右,所以先分左(3),然后右(8)。分完之后排序,然后在合成,下图为排序过程
那么可以知道他的排序顺序
那么是如何合成的以9 7 1 3 8 与 2 5 4 6来讲
9索引为left(0),2索引为mid+1(mid=(left+right)/2),在此之前创建一个新的数组,然后比较array[left]与array[mid+1]的大小,我们这里从小到大排序,所以让小的进数组,那么可能有一种特殊情况,就是左边或者右边的数组的数全部存进新数组了。此时就不用比较了在,直接将一个数组剩的数放进新数组即可,因为这两个数组之内的都是排好的(上图圈3和圈6)
那么归并排序就是这样的原理。全部代码如下:
#include "stdio.h"
#define lengh 20
void println(int num[],int len){
int i =0;
for(i=0;i<len;i++){
printf("%d",num[i]);
}
}
void paixu(int num[],int left,int right,int mid){
int i=left;
int j=mid+1;
int k = 0;
int array[lengh];
while(i<=mid&&j<=right){
if(num[i]<=num[j]){
array[k++]=num[i++];
}
else if(num[i]>num[j]){
array[k++]=num[j++];
}
}
if(i==mid+1){
while(j<=right){
array[k++]=num[j++];
}
}
if(j==right+1){
while(i<=mid){
array[k++]=num[i++];
}
}
for(j=0,i=left;j<k;i++,j++){
num[i]=array[j];
// printf("%d",array[j]);
}
}
void fen(int num[],int left,int right,int flage){
// if(flage==0){
// printf("%d\n",1);
// }else if(flage==1){
// printf("%d\n",2);
// }else if(flage==2){
// printf("%d\n",3);
// }
// printf("%d%d\n",num[left],num[right]);
if(left<right){
int mid=(left+right)/2;
// printf("%d%dmid=%d\n",left,right,mid);
fen(num,left,mid,1);
fen(num,mid+1,right,2);
paixu(num,left,right,mid);
//merge(num,left,mid,right);
// printf("%d\n",555);
}
}
int main(){
int a[9]={9,7,1,3,8,2,5,4,6};
fen(a,0,8,0);
println(a,9);
return 0;
}