>>归并排序
听到用到最多的还是冒泡排序和快速排序,归并排序只知其名,但是我还没实际使用过,今天又重新去理解它,发现它有快速排序的影子(分治递归),且这两个排序都是高效的高级排序,所以给了我一种印象:这种思想非常高大上,但当你仔细去瞧它,又觉得它平易近人。
归并排序的思路: 给定一个数组,将数组分为两部分,先让左边的有序,在让右边的有序,最后将两部本合并。左边部分和右边部分又依次递归。
平均时间复杂度: O(n log n)
最好情况: O(n log n)
最坏情况: O(n log n)
空间复杂度: O(n)
稳定性: 稳定
: ) 递归实现归并排序
代码如下:
/*
* 两个辅助函数,第一个函数:递归; 第二个函数:排序
* */
public static void mergeSort(int[] value,int length){
sort(value,0,length-1);//转入递归
}
private static void sort(int[] value,int l,int r){
//递归结束的条件
if(l>=r) return;
//这里使用了位运算,但是完全可以使用 /。
int mid=l+((r-l)>>1); // (l+r)>>1
sort(value,l,mid);
sort(value,mid+1,r);
merge(value,l,mid,r);
}
private static void merge(int[] value,int l,int mid,int r){
int[] temp=new int[r-l+1];
int i=0;
int p1=l;
int p2=mid+1;
//依次排入左边和右边的数
while(p1<=mid&&p2<=r){
temp[i++]=value[p1]<value[p2]?value[p1++]:value[p2++];
}
//将剩下的输排入
while(p1<=mid){
temp[i++]=value[p1++];
}
while(p2<=r){
temp[i++]=value[p2++];
}
for(int j=0;j<temp.length;j++){
value[l+j]=temp[j];
}
}
这是归并排序的递归实现。
本来我是想试试自己写归并的迭代实现,但是看了《递归转迭代》这篇博客之后就放弃了。
摘录一句话:
虽然将递归函数转换为迭代函数可以提高程序效率,但是转换后的迭代函数往往可读性差,难以理解,不易维护。所以只有在特殊情况下,比如对栈空间有严格要求的嵌入式系统,才需要转换递归函数。大部分情况下,递归并不会成为系统的性能瓶颈,一个代码简单易读的递归函数常常比迭代函数更易维护。