3、希尔排序
思想是:首先,比较相隔最远的元素;然后比较距离次远的元素,依次类推,逐渐向基本的插入排序靠拢。
实际中,甚至在N为上万的情况下,希尔排序的性能也是相当好的。代码的简单性使它成为排序中等规模输入的良好算法。
平均运行时间降到O(N[size=xx-small]5/4[/size])
4、归并排序
运行时间是O(NlogN),但几乎不用它作为内存排序算法。问题在于归并两个有序数组需要额外内存,另外还有复制临时数组拷回原数组的额外操作。
/*
* Shellsort, using a sequence suggested by Gonnet.
* @param a an array of Comparable items.
*/
public static void shellsort( Comparable [] a ){
for( int gap = a.length / 2; gap > 0; gap = gap==2?1:(int) (gap/2.2))
for( int i = gap; i< a.length; i++){
Comparable tmp = a[i];
int j = i;
for( ; j > gap && tmp.compareTo( a[j-gap]) < 0; j -= gap)
a[j] = a[j-gap];
a[j] = tmp;
}
}
思想是:首先,比较相隔最远的元素;然后比较距离次远的元素,依次类推,逐渐向基本的插入排序靠拢。
实际中,甚至在N为上万的情况下,希尔排序的性能也是相当好的。代码的简单性使它成为排序中等规模输入的良好算法。
平均运行时间降到O(N[size=xx-small]5/4[/size])
4、归并排序
/*
* Mergesort algorithm.
* @param a an array of Comparable items.
*/
public static void mergeSort( Comparable [] a){
Comparable [] tmpArray = new Comparable[a.length];
mergeSort( a, tmpArray, 0 , a.length-1 );
}
/*
* Internal method that makes recursive calls.
* @param a an array of Comparable items.
* @param tmpArray an array to place the merged result.
* @param left the left-most index of the subarray.
* @param right the right-most index of the subarray.
*/
private static void mergeSort( Comparable [] a, Comparable[] tmpArray, int left, int right){
if( left < right ){
int center = (left + right) / 2;
mergeSort(a, tmpArray, left, center);
mergeSort(a, tmpArray, center + 1, right);
merge(a, tmpArray, left, center+1, right);
}
}
/*
* Internal method that merges two sorted halves of a subarray.
* @param a an array of Comparable items.
* @param tmpArray an array to place the merged result.
* @param leftPos the left-most index of the subarray.
* @param rightPos the index of the start of the second half.
* @param rightEnd the right-most index of the subarray.
*/
private static void merge(Comparable [] a, Comparable [] tmpArray,
int leftPos, int rightPos, int rightEnd){
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while( leftPos <= leftEnd && rightPos <= rightEnd)
if (a[leftPos].compareTo( a[rightPos] ) < 0 )
tmpArray[tmpPos++] = a[leftPos++];
else
tmpArray[tmpPos++] = a[rightPos++];
while ( leftPos <= leftEnd )
tmpArray[tmpPos++] = a[leftPos++];
while ( rightPos <= rightEnd )
tmpArray[tmpPos++] = a[rightPos++];
for( int i=0; i< numElements; i++, rightEnd --)
a[rightEnd] = tmpArray[rightEnd];
}
运行时间是O(NlogN),但几乎不用它作为内存排序算法。问题在于归并两个有序数组需要额外内存,另外还有复制临时数组拷回原数组的额外操作。