文章目录
- 核心思想
- 快速排序基础版
- 快速排序优化版
- 思路(同时找最大和最小)
核心思想
选择排序是一种简单的 原地比较排序算法,其核心思想是:
每次从未排序部分选择最小(或最大)元素,放到已排序部分的末尾。
快速排序基础版
public class SelectSort{public static void selectSort(int[] arr){int n = arr.length;for(int i = 0; i < n - 1; i++){int minIndex = i;for(int j = i +1; j < n ; j++){if(arr[j] < arr[minIndex]){minIndex = j;}}swap(arr, i, minIndex);}}private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}
时间复杂度:
- 最好/最坏/平均情况均为 O(n²)(每次必须扫描剩余未排序部分)。
- 比较次数:n(n-1)/2 次,与输入数据无关。
空间复杂度:O(1)(原地排序)。
稳定性:不稳定(交换可能破坏相等元素的相对顺序)。
补充:为什么选择排序不稳定?
示例:
原始数组 [5₁, 2, 5₂, 1](5₁ 和 5₂ 是值相同的两个元素)。
第一轮选择最小元素 1,与 5₁ 交换 → [1, 2, 5₂, 5₁]。
此时 5₂ 跑到了 5₁ 前面,相对顺序改变。
根本原因:
交换操作可能跨越多个位置,破坏相等元素的原始顺序。
快速排序优化版
思路(同时找最大和最小)
基础版就是每次在未排序的数中选一个最小的放到左边已排序的末尾,而优化版的快速排序就是每次不仅把最小的放到左边,也把最大的放到右边,减少遍历次数,这里的实现要结合双指针
public class OptimizedSelectionSort{public static void optimizedSelectionSort(int[] arr){int left = 0, right = arr.length - 1;while(left < right){int minIndex = left;int maxIndex = right;// 1. 找到当前未排序部分的最小和最大值索引for(int i = left; i <= right; i++){if(arr[i] < arr[minIndex]) minIndex = i;if(arr[i] > arr[maxIndex]) maxIndex = i;}}swap(arr, left, minIndex);// 注意:如果最大值原本在left位置,它可能被换到minIndex位置if(maxIndex == left){maxIndex = minIndex;}swap(arr, right, maxIndex);}
}
- 每轮同时找到最小和最大值,减少总轮数(从 n 轮减少到 n/2 轮)。