今天学习到了新算法,归并排序;归并排序算法的思想和快速排序有点类似;但仔细一想区别还是挺大;
推荐文章点击打开链接
本文仅供自己参考,写这篇文章只是为了记录学了什么~
归并排序(从下往上):将数组分为n个长度为2的数组,然后再将相邻数组合并排序,直到合并为完整数组;
我写归并的思路:
1、将整个数组分成n个长度为len的子数组(len初始值为2)
2、分别对子数组排序;
3、递归合并相邻数组,重复1,2;每次递归len*2;
4、递归出口:len>数组长度;
public void Merge(int[]a,int length) {
int arrlen =a.length;
for(int i = 0;i<arrlen;i+=length) {
pp(a,i,length);//排序,区间【i,i+length】
}
if(length >=arrlen )return;
Merge(a,2*length);
}
/**
*
* 在这里选择:插入排序,因为合并的相邻数组相对有序
* @param a
* @param i 数组起始位置
* @param len
*/
public void pp(int[]a ,int i,int len) {
int glen = -1;
if(i+len <=a.length)
glen=i+len;
else
glen =a.length;
for(int j = i+1;j<glen;j++) {
if(a[j] >= a[j-1])continue;
int x =j;
int xx=a[j];
while( j > i && xx < a[j-1]) {
a[j]=a[j-1];
j--;
}
a[j] = xx;
j=x;
}
}
感觉还有太多地方需要改进;其中插入排序这个地方还是可以改进的;
整体感觉归并的这种写法不好,这次就先写到这里,明天有空改进了再写
=================20180611=========================
对于上面算法的改进,没有什么动力。因为这种改进,没有对自己思考上的提升;
下面来看下
归并排序的另一种解法:
1、将数组二分;
2、递归,继续将2个子数组二分;
3、出口right >mid;
先看代码:
public static void merge1(int[]a,int left,int mid,int right) {
if(mid < right) {
merge1(a,left,(left+mid)/2,mid);
merge1(a,mid+1,(right+mid+1)/2,right);
}
merge(a,left,mid,right);//对数组在[left,right]区间的排序
}
看到代码之后自然不难理解为什么出口条件的设置;
这个方法最精髓的地方,就是巧妙的利用递归将数组二分;