选择排序(Selection Sort )分为两种 简单选择排序(Simple Selection Sort) 和树形选择排序。 简单选择排序(Simple Selection Sort): 简单选择排序类似于冒泡排序(Bubble Sort) ,每次都会在剩下的元素集合中选择出一个值出来填充到当前位置。的区别是,冒泡排序在每次发现比当前值小于(或大于)时,都会交换元素的位置, 而 简单选择排序是选择剩余元素中的值和当前位置交换数据。 比如对于元素集合R={37, 40, 38, 42, 461, 5, 7, 9, 12} 在第一趟排序中:37直接和5交换, 形成新的序列 R1={5,40,38,42,461,37,7,9,12} 在第二趟排序中:40直接和7交换, 形成新的序列 R2={5,7,38,42,461,37,40,9,12} 以此类推,直到后一个元素(注意:在第二趟排序中,38比42小,但是他们并没有交换数据)。 以下是简单选择排序的一个Java实现版本: public static void selectionSort(int[] data) { if (data == null || data.length <= 1) return; int i, j, value, minPos, len = data.length; int outer = len - 1, tmp; for (i = 0; i < outer; i++) { value = data[i]; minPos = -1; for (j = i + 1; j < len; j++) { if (data[j] < value) { minPos = j; value = data[j]; } } if (minPos != -1) { tmp = data[i]; data[i] = value; data[minPos] = tmp; } // for (int k = 0; k < len; k++) { // System.out.print(data[k] + " , "); // } // System.out.println(); } } public static void main(String[] args) { int[] coll = { 37, 40, 38, 42, 461, 5, 7, 9, 12 }; selectionSort(coll); for (int i = 0; i < coll.length; i++) { System.out.print(coll[i] + " , "); } }
树选择排序(Tree Selection Sort) 树选择排序算法相对于简单选择排序来说是典型的以空间换时间的算法。其思想是对待排序的 N 个元素 , 构造出相对较小的 (n+1)/2个数,然后再构造出相对较小的[n+1]/4个数,直到只有一个元素为止。构造成一个完全二叉树。 排序的时候,那个元素是小的,取出该小元素,将该元素替换为"大值",再调整完全二叉树。 下面是树形选择排序的一个Java实现版: public static void treeSelectionSort(int[] data) { if (data == null || data.length <= 1) return; int len = data.length , low = 0 , i , j; // add Auxiliary Space int[] tmp = new int[2*len -1]; int tSize = tmp.length; //construct a tree for(i =len-1 , j=tmp.length-1;i >=0 ;i--,j--){ tmp[j]=data[i]; } for(i = tSize -1 ; i > 0 ; i-=2){ tmp[(i-1)/2] = tmp[i] > tmp[i-1]? tmp[i-1]:tmp[i]; } //end //remove the minimum node. while(low < len){ data[low++] = tmp[0]; for(j=tSize-1;tmp[j]!=tmp[0];j--); tmp[j] = Integer.MAX_VALUE; while(j > 0){ if(j%2 == 0){ //如果是右节点 tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j]; j = (j-1)/2; }else{ //如果是左节点 tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j]; j = j/2; } } } } 在构造完全二叉树的时候对 N 个元素的集合, 需要 2*N -1 个辅助空间。 代码: while(j > 0){ if(j%2 == 0){ //如果是右节点 tmp[(j-1)/2] = tmp[j] > tmp[j-1]?tmp[j-1]:tmp[j]; j = (j-1)/2; }else{ //如果是左节点 tmp[j/2]=tmp[j] > tmp[j+1]? tmp[j+1]:tmp[j]; j = j/2; } } 则实现递归的构造新集合中的小值。