1. 图示过程
说明:此图示为未优化的选择排序示意图,意在说明原理
2. 动图展示
说明:此动图为优化后的选择排序,每趟只交换一次
3. 文字叙述过程
- 第1趟比较:拿第1个元素依次和它后面的每个元素进行比较,如果第1个元素大于后面某个元素,交换它们,经过第1趟比较,数组中最小的元素被选出,它被排在第一位
- 第2趟比较:拿第2个元素依次和它后面的每个元素进行比较,如果第2个元素大于后面某个元素,交换它们,经过第2趟比较,数组中第2小的元素被选出,它被排在第二位
- ......
- 第n-1趟比较:第n-1个元素和第n个元素作比较,如果第n-1个元素大于第n个元素,交换它们
4. Java代码实现
public static void selectionSort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
for(int i = 0; i < nums.length - 1; i++) {
for(int j = i + 1; j < nums.length; j++) {
if(nums[i] > nums[j]) {
swap(nums, i, j);
}
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
5. 复杂度
- 时间复杂度:O(n²)
- 空间复杂度:O(1),只需要一个附加程序单元用于交换
- 稳定性:选择排序是不稳定的排序算法,因为无法保证值相等的元素的相对位置不变,例如 [3, 4, 3, 1, 5]这个数组,第一次交换,第一个3和1交换位置,此时原来两个3的相对位置发生了变化。
6. 优化
上面的算法的缺点:在每趟比较过程中,一旦发现某个元素比第1位的元素小,就交换它们,但这是没必要的,徒增了交换的次数。
优化:选择排序的核心是,在每趟比较中,找到本趟中最小的元素放在本趟比较的第1个位置,所以选择排序的每趟比较只需要交换一次即可,只要找到本趟比较中最小的元素和本趟比较中第1位置的元素交换即可。
public static void selectionSort(int[] nums) {
if (nums == null || nums.length < 2) {
return;
}
for(int i = 0; i < nums.length - 1; i++) {
int minIndex = i;
for(int j = i + 1; j < nums.length; j++) {
if(nums[i] > nums[j]) {
minIndex = nums[j] < nums[minIndex] ? j : minIndex;
}
}
swap(nums, i, minIndex);
}
}
网友评论