《Java数据结构和算法》学习笔记(5)——递归 归并排序

[b]每篇笔记都会附上随书的Applet演示程序,有算法看不明白的,可以[url="http://yuan.iteye.com/topics/download/7977acc8-b69e-3b4d-8ba7-00adf8688b63"]下载Applet[/url]运行起来(直接打开html文件即可),可以很容易地看清楚算法的每一步。[/b]
方法调用自身,就构成了[b]递归[/b]调用,通常递归都有个终止条件,否则程序无法停止运行。
[align=center][size=large][b]归并排序[/b][/size][/align]
[b]归并排序[/b]的原理(升序排序)是将两个有序数组合并成一个有序数组,先对比两个数组的[b]第1项[/b],如果[b]数组a的第1项[/b]大于[b]数组b的第1项[/b],那么将[b]数组b的第1项[/b]复制到新数组中。接着对比[b]数组a的第1项[/b]和[b]数组b的第2项[/b],再把更小的一项放到[b]新数组的第2个位置[/b]上……直到合并完成。
递归的过程是一个不断分割数组的过程,把原数组不断的分割成两半,直到不能再分割(长度为1),则返回,然后开始合并。
代码如下:
	@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void mergeSort(T[] array){
T[] workspace = (T[])new Comparable[array.length];
recallMergeSort(array, workspace, 0, array.length - 1);
}

private static <T extends Comparable<? super T>> void recallMergeSort
(T[] array, T[] workspace, int lowerBound, int upperBound){
if(upperBound == lowerBound){
return;
}else{
int midIndex = (upperBound + lowerBound) / 2;
recallMergeSort(array, workspace, lowerBound, midIndex);
recallMergeSort(array, workspace, midIndex + 1, upperBound);
merge(array, workspace, lowerBound, midIndex + 1, upperBound);
}
}

private static <T extends Comparable<? super T>> void merge
(T[] array, T[] workspace, int lowerIndex, int higherIndex, int upperBound){
int i = 0;
int midIndex = higherIndex - 1;
int lowerBound = lowerIndex;
while(lowerIndex <= midIndex && higherIndex <= upperBound){
if(array[lowerIndex].compareTo(array[higherIndex]) < 0)
workspace[i++] = array[lowerIndex++];
else
workspace[i++] = array[higherIndex++];
}

while(lowerIndex <= midIndex)
workspace[i++] = array[lowerIndex++];

while(higherIndex <= upperBound)
workspace[i++] = array[higherIndex++];

for(i=lowerBound; i<=upperBound; i++)
array[i] = workspace[i - lowerBound];
}

归并排序的时间复杂度是O(N*logN),比表插入排序法快得多,但需要[b]多1倍的内存空间[/b]。对长度为1万的数组排序,时间几乎算不出来(几乎为0),因为我把数组扩大10倍,经测试,对随机数组进行排序需要0.094秒,逆序排序需要0.11秒。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值