高级排序之所以高级的地方就是快········!好像是句废话!
高级排序有希尔排序和快速排序,还有基于划分思想的快速排序,至于基数排序额········作为了解吧!
希尔排序是基于插入排序的也就是简单排序里那个最快的! 但是大大的减少了插入次数!
import java.util.*; public class ShellSort { public static void shellSort(Comparable[] data){ int j; for( int gap = data.length / 2; gap > 0; gap /= 2){ for( int i = gap; i < data.length; i++){ Comparable temp = data[i]; for(j = i; j >= gap && temp.compareTo(data[j - gap]) < 0; j -= gap){ data[j] = data[j - gap]; } data[j] = temp; } } } public static void main(String[] args){ Random r = new Random(); Comparable[] data = new Comparable[20]; for( int i = 0; i < data.length; i++){ data[i] = r.nextInt(data.length); } for( int i = 0; i < data.length; i++) System.out.print(data[i] + " "); shellSort(data); System.out.println(); for( int i = 0; i < data.length; i++) System.out.print(data[i] + " "); } }
快速排序是基于划分思想,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
public class QuickSort {
publicstaticint[] QuickSort(int[] pData, int left, int right) {
int i= left, j= right; int middle, strTemp; middle = pData[(left + right) / 2]; do { while ((pData[i] < middle) && (i < right)) i++; while ((pData[j] > middle) && (j > left)) j--; if (i <= j) { strTemp = pData[i]; pData[i] = pData[j]; pData[j] = strTemp; i++; j--; } } while (i <= j); for (int t = 0; t < pData.length; t++) System.out.print(pData[t] + " "); System.out.println(""); if (left < j) { QuickSort(pData, left, j); } if (right > i) QuickSort(pData, i, right); return pData; } public static void main(String[] argv) { int[] pData = { 1,84, 85, 67,600, 88,999 }; QuickSort0(pData, 0, pData.length - 1); }}拿到一个元素比他小的放左边,比他大的放右边,然后已经分好的两边的元素再递归调用,然后再分,再左小右大!
基数排序
(radixsort)则是属于“分配式排序”(distribution sort),基数排序法又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的比较性排序法。
基数排序(Radix sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。基数排序的发明可以追溯到1887年赫尔曼·何乐礼在打孔卡片制表机(Tabulation Machine)上的贡献[1]。
它是这样实现的: 将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零. 然后, 从最低位开始, 依次进行一次排序.这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列.
基数排序的方式可以采用LSD(Least significantdigital)或MSD(Most significantdigital),LSD的排序方式由键值的最右边开始,而MSD则相反,由键值的最左边开始。
以LSD为例,假设原来有一串数值如下所示:
73,22, 93, 43, 55, 14, 28, 65, 39, 81
首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:
0
1 81
2 22
3 73 93 43
4 14
5 55 65
6
7
8 28
9 39
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
81,22, 73, 93, 43, 14, 55, 65, 28, 39
接着再进行一次分配,这次是根据十位数来分配:
0
1 14
2 22 28
3 39
4 43
5 55
6 65
7 73
8 81
9 93
接下来将这些桶子中的数值重新串接起来,成为以下的数列:
14,22, 28, 39, 43, 55, 65, 73, 81, 93
这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。
LSD的基数排序适用于位数小的数列,如果位数多的话,使用MSD的效率会比较好,MSD的方式恰与LSD相反,是由高位数为基底开始进行分配,其他的演算方式则都是相同。
public class RadixSort { public static void sort( int[] number, int d) { int k=0; int n=1; int m=1; int[][] temp = new int[number.length][number.length]; int[] order = new int[number.length]; while(m <= d) { for( int i = 0; i < number.length; i++) { int lsd = ((number[i] / n) % 10); temp[lsd][order[lsd]] = number[i]; order[lsd]++; } for( int i = 0; i < d; i++) { if(order[i] != 0) for( int j = 0; j < order[i]; j++) { number[k] = temp[i][j]; k++; } order[i] = 0; } n *= 10; k = 0; m++; } } public static void main(String[] args) { int[] data = {73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100}; RadixSort.sort(data, 10); for( int i = 0; i < data.length; i++) { System.out.print(data[i] + " "); }
}