[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),则返回,然后开始合并。
代码如下:
归并排序的时间复杂度是O(N*logN),比表插入排序法快得多,但需要[b]多1倍的内存空间[/b]。对长度为1万的数组排序,时间几乎算不出来(几乎为0),因为我把数组扩大10倍,经测试,对随机数组进行排序需要0.094秒,逆序排序需要0.11秒。
方法调用自身,就构成了[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秒。