选择排序定义
选择排序的整体的思想就是,我们在一个序列当中选出一个最小的(本文以升序为例),然后和第一个元素交换,然后后面再在剩下的找最小的,再和第二个元素交换,以此类推,前面部分的数据慢慢变得有序,直到最终得到一个完全有序的数据。
代码实现
public static void selectSort(int[] arr) {
int len = arr.length;
for(int i=0; i<len; i++) {
int index = i;//初始化index,指向还未排序的数据中的第一个位置
for(int j=i+1; j<len; j++) {//每次内部循序找出最小值的位置
if(arr[j] < arr[index]) {
index = j;//记录当前最小值位置
}
}
//结束一次内循环后,找出一个最小值,交换前面
swap(arr, index, i);
}
System.out.println("selectSort: "+Arrays.toString(arr));
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
选择排序的优化
在上面的内循环中,每次循环我们只找出了最小值并放到前面的位置,其实我们还可以同时找出最大值,并放到后面的位置,这种方式,也叫作二元排序。在网上看到很多二元排序,其实都是错误的,也不知道坐着有没有执行代码进行测试,本例的实现如下:
public static void selectSort2(int[] arr) {
int len = arr.length;
//由于前后同时进行, 所以最外层循环只需要进行到中间即可
for(int i=0; i<(len/2 + 1); i++) {
int index_min = i;//初始化最小值的索引位置
int index_max = len -i -1;//初始化最大值的索引位置
for(int j=i; j<len -i; j++) {//每次内部循序找出最小值的位置
if(arr[j] < arr[index_min]) {
index_min = j;//记录当前最小值位置
}
if(arr[j] > arr[index_max]) {
index_max = j;//记录当前最大值位置
}
}
//结束一次内循环后,找出一个最小值,交换前面
swap(arr, index_min, i);
//交换小的数到最前面以后,需要进行一次判断
//如果最大值刚好在最前面的位置,由于先把最小值交换到最前面,此时最大值的位置就改变了,那么相应的,最大值的脚标应该修改一下
if(i == index_max) {
//此处也是很多网上例子错误的最大原因:没有执行交换动作
index_max = index_min;
}
swap(arr, index_max, len -i -1);
}
System.out.println("selectSort2: "+Arrays.toString(arr));
}
附上自动生成测试数组的代码
public static int[] randomArray(int length) {
int[] arr = new int[length];
Random random = new Random();
for(int i=0; i<length; i++) {
arr[i] = random.nextInt(100);
}
//自动生成随机数组,先进行一次原始数据打印
System.out.println(Arrays.toString(arr));
return arr;
}