算法思路
选择排序的原理,从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。其步骤可总结为:
- 在arr[0~N-1]范围上,找到最小值所在的位置,然后把最小值交换到0位置。
- 在arr[1~N-1]范围上,找到最小值所在的位置,然后把最小值交换到1位置。
- 在arr[2~N-1]范围上,找到最小值所在的位置,然后把最小值交换到2位置。
…
时间复杂度
假设数组长度为N,在每一个步骤中,需要的操作有:遍历剩余未排序的元素,与最小值进行比较,得到最小值之后进行交换,相当于需要N次操作。一共有N个步骤,所以选择排序的复杂度为O(N2)。
代码
public class SelectionSort {
/**
* 选择排序:
* 0 ~ N-1 找到最小值,放到0位置上
* 1 ~ n-1 找到最小值,放到1位置上
* 2 ~ n-1 找到最小值,放到2位置上
* ...
*/
public static void selectionSort(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < nums.length; j++) {
// 找到最小值所在的位置
minIndex = nums[j] < nums[minIndex] ? j : minIndex;
}
// 将最小值放到i位置上
ArrayUtil.swap(nums, i, minIndex);
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int[] nums = ArrayUtil.generateRandomArray(20, 30);
selectionSort(nums);
ArrayUtil.printArray(nums);
}
}
}
public class ArrayUtil {
private ArrayUtil() {}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void printArray(int[] arr) {
if (arr == null)
return;
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
}
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
}