首页 > 代码库 > 归并排序 分治+递归
归并排序 分治+递归
0 1 2 3 4 5 6 7 8 //下标
{ 9 , 4 , 3 , 7 , 3 , 8 , 2 , 4 , 8 }//通过mergesort函数递归 来切 开始的时候fir=0, las=8, mid=4 所以下标0-4,分为前组 5-8分为后组
{ 9 , 4 , 3 , 7 , 3 }{ 8 , 2 , 4 , 8 }
{ 9 , 4 , 3 }{ 7 , 3 }{ 8 , 2 }{ 4 , 8 }
{ 9 , 4 }{ 3 }{ 7 }{3 }{ 8 }{ 2 }{ 4 }{ 8 }
{ 9 }{ 4 }{ 3 }{ 7 }{3 }{ 8 }{ 2 }{ 4 }{ 8 }
-------------------到现在为止,就已经用mergesort() 切割完了, 所有的子集fir==las, 不会再分了, 这时开始递归分治.之前mergesort()里的mergearr()会开始执行
{ 4 , 9 }{ 3 }{ 7 }{ 3 }{ 8 }{ 2 }{ 4 }{ 8 } 最先的两个数会首先按大小排序好. 存到数组tem再返回到数组a . 所以4 和9 虽然换位子了, 但是占的还是原来的这两个位置.
{ 3 , 4 , 9 }{ 3 , 7 }{ 2 , 8 }{ 4 , 8 } 这是次递归.
{ 3 , 3 , 4 , 7 , 9}{ 2 , 4 , 8 , 8 }
{ 2, 3 , 3 , 4 , 4 , 7 , 8 , 8 , 9 } 结束,输出a数组;
怕排版坏掉,传上图.
#include<stdio.h> int a[500]={9,4,3,7,3,8,2,4,8}; int tem[500]; void mergearr(int fir,int mid,int las)// 分治法, 最先合并的是最前面两个数字. { int i=fir,j=mid+1; int n=mid,m=las; int k=0; while(i<=n&&j<=m) { if(a[i]<a[j]) tem[k++]=a[i++]; else tem[k++]=a[j++]; } while(i<=n) { tem[k++]=a[i++]; } while(j<=m) { tem[k++]=a[j++]; } for(i=0;fir<=las;) { a[fir++]=tem[i++]; } } void mergesort(int fir,int las)//切开成小段 { int mid; if(fir<las) { mid=(fir+las)/2; mergesort(fir,mid); mergesort(mid+1,las); mergearr(fir,mid,las); } } int main() { int i,n; n=9; mergesort(0,8); for(i=0;i<n;i++) { printf("%d\n",a[i]); } while(1); return 0; }