第一次归并:
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
23 |
8 |
19 |
33 |
15 |
6 |
27 |
↑ ↑
i j
最开始i指向a[0],j指向a[1],比较a[0],a[1]大小,并进行swap
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
23 |
19 |
33 |
6 |
15 |
27 |
↑ ↑
i j
i指向j时候归并结束
第二次归并:
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
23 |
19 |
33 |
6 |
15 |
27 |
↑ ↑
i j
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
23 |
19 |
33 |
6 |
15 |
27 |
↑ ↑
i j
i向后移动,直到找到比j指向的数大的那个数,此时,i之前的数是两段数值中最小的数
j原来的位置标记为Index,j向后移动找到比此时i指向的数大的数.
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
23 |
19 |
33 |
6 |
15 |
27 |
↑ ↑ ↑
i index j
则此时a[Index,j]之间的数小于a[i,index]之间的数,将此两段数值互换,得到
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
19 |
23 |
33 |
6 |
15 |
27 |
↑ ↑
i j
互换以后需要调整i的位置,将i向后移动index-j个单位【i+=(j-index)】
找到第一个比j指向的数大的,即此时i指向j,第二次归并结束。
第三次归并:
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
19 |
23 |
33 |
6 |
15 |
27 |
↑ ↑
i j
重复上述步骤,在此归并中,第一次比较时i不动,j指向a[5]
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
8 |
19 |
23 |
33 |
6 |
15 |
27 |
↑ ↑ ↑
i index j
交换a[index,j]和a[i,index]两段数据,i+=(j-index)
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
19 |
23 |
33 |
15 |
27 |
↑ ↑ i j
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
19 |
23 |
33 |
15 |
27 |
↑ ↑
i j
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
19 |
23 |
33 |
15 |
27 |
↑ ↑ ↑
i index j
swap(i,j,index)
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
15 |
19 |
23 |
33 |
27 |
↑ ↑
i j
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
15 |
19 |
23 |
33 |
27 |
↑ ↑
i j
此时j任然指向a[6],index也指向a[6],交换
a[0] |
a[1] |
a[2] |
a[3] |
a[4] |
a[5] |
a[6] |
6 |
8 |
15 |
19 |
23 |
27 |
33 |
↑ ↑
i j
i之后第一个比j指向的数大的数为33,此时i=j,归并结束
代码还没写完。。。。。脑子笨,感觉不大对,再改看看吧。pow这个函数总觉得用的不大对,这两天看看别人写的代码再找找思路看。
void in_palce_merge_sort(double* a,int n){ int index; int edge=0; int i=0;//第一段有序数组入口 int j=1;//第二段有序数组入口 int inpoint=0; while(pow(2,edge)<n){ while(a[i]<a[j]&&i<j) i++; index=j; while(a[j]<a[i]&&j<inpoint+pow(2,edge)) j++; swap(a[i],a[j],a[index]); i+=(j-index); if(i==j&&i<n){ i++; //此时往后移一位即新的有序数组的入口 j=i+pow(2,edge); //等下考虑下2倍 inpoint=j; } else if(i==n){ edge++; i=0; j=pow(2,edge); inpoint=j; } } }
关于swap(),个人想到的是需要一段临时空间作为暂存空间进行交换,如果这样的话感觉就失去原地归并的意义了,其他搜索到有手摇算法,等仔细研究下再来修改。