选择排序
基本思想
- 找到数组中最小的那个元素;
- 将它和数组的第一个元素交换位置(如果第一个元素就是最小元素,那么它就和自己交换);
- 在剩下的元素中找出最小的元素,将它与剩余元素中的第一个元素交换(即数组第二个元素);
- 重复执行 3 ,直到将整个数组排序。
//选择一个最小 /最大 的数安放到正确的位置
public class SelectSort {
public static void main(String[] args) {
int arr[] = {101, 115, 119, 1};
System.out.println("排序前");
System.out.println(Arrays.toString(arr));
selectSort(arr);
}
public static void selectSort(int arr[]) {
//使用逐步推导的方式
//算法思想 先简单 到复杂
//原始的数组 101 115 119 1
//第一轮 1 34 119 101
for (int i = 0; i < arr.length -1; i++) {
int minIndex = i; //假定最小值的下标为0
for (int j = i + 1; j < arr.length; j++) {
if (arr[minIndex] > arr[j]) { //说明假定的最小值 并不是最小值
minIndex = j; //重置最小值的下标
}
}
if (minIndex != i) {
swap(arr,i,minIndex);
}
System.out.println("第"+(i+1)+"轮的排序");
System.out.println(Arrays.toString(arr));
}
}
static void swap(int arr[],int i,int j){
int temp = 0;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
优化方案
试想,上述方案中的主要思路是,每次遍历剩余元素,找出其中最小值,只排定最小值。(原有方案)
每次遍历剩余元素的时候,找出其中最小值和最大值,并排定最小值和最大值。(优化方案)
这样遍历的次数会减少一半。时间复杂度是O(N/2 * N /2),还是平方级别的。但是运行时间有了相应的减少。
public class SelectSort {
public static void main(String[] args) {
int arr[] = {9, 5, 10, 2, 4, 6, 7, 1,-2};
selectSort(arr);
}
public static void selectSort(int arr[]) {
for (int i = 0; i < arr.length/2; i++) {
int minIndex = i; //假定最小值的下标为0
int maxIndex = i;
// int arr[] = {9, 5, 4, 2, 4, 6, 7, 1,10};
// j < arr.length-i
// ”-i“ 防止最大值一直不变
for (int j = i + 1; j < arr.length - i; j++) {
if (arr[minIndex] > arr[j]) { //说明假定的最小值 并不是最小值
minIndex = j; //重置最小值的下标 最小值地址 7
}
if (arr[maxIndex] < arr[j]){
maxIndex = j; //最大值地址8
}
}
swap(arr,i,minIndex);
//因为先确定的是最小值,所以修正 最大值在 i 位置的情况
//比如说 此时交换完之后,数组变为:【1, 5, 4, 2, 4, 6, 7,9】
//交换之后,maxPos由 0 --> 7 即 maxPos = minPos;
if (maxIndex == i) {
maxIndex = minIndex;
}
//arr.length -1-i 最后一个数
swap(arr, arr.length -1-i,maxIndex);
System.out.println("第"+(i+1)+"轮的排序");
System.out.println(Arrays.toString(arr));
}
}
static void swap(int arr[],int i,int j){
int temp = 0;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}