读书人

惯用排序算法-java实现(希尔归并)

发布时间: 2012-12-24 10:43:14 作者: rapoo

常用排序算法-java实现(希尔,归并)
3、希尔排序

/** 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(N5/4)

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),但几乎不用它作为内存排序算法。问题在于归并两个有序数组需要额外内存,另外还有复制临时数组拷回原数组的额外操作。

读书人网 >编程

热点推荐