上篇咱们好好聊了聊冒泡排序,这篇咱们来聊聊另外一种初级排序算法——选择排序java
选择排序的算法思路一样很简单。仍是数组为例,咱们如今有个整数数组,要求将其中整数元素按值的大小从小到大排个序。选择排序的具体思路是这样:先从头遍历数组,找出其中值最小的那个元素,而后将其值同遍历区间最开始那个元素交换,若是值最小的元素恰是最开始那个元素,就本身跟本身交换值。第一遍遍历完成,数组中最小的值已是数组第一个元素,此时数组第一个元素已部分有序,将从新遍历的初始下标加一,开始下次遍历,如此循环,直至遍历区间内只剩一个元素,此时数组已总体有序。算法
来具象化捋一遍选择排序的逻辑:数组
``函数
设现有无序数组 a = [40, 50, 20, 30, 10]
其有序状态应为 a = [10, 20, 30, 40, 50]
咱们对其作下选择排序,具象展现以下:
数组下标:a[0] a[1] a[2] a[3] a[4]
初始值: 40 50 20 30 10
第一次选择遍历过程: 40 50 20 30 10 (遍历区间值最小元素为a[4],
↑ ↑ 与遍历区间初始下标a[0]交换值)
第二次选择遍历过程: 10 50 20 30 40 (最小元素为a[2],与a[1]交换值,
--- ↑ ↑ 下划线标示的元素已部分有序)
第三次选择遍历过程: 10 20 50 30 40 (最小元素为a[3],与a[2]交换值,
-------- ↑ ↑ 下划线标示的元素已部分有序)
第四次选择遍历过程: 10 20 30 50 40 (最小元素为a[4],与a[3]交换值,
------------ ↑ ↑ 下划线标示的元素已部分有序)
第五次选择遍历过程: 10 20 30 40 50 (遍历区间内只剩一个元素了,
------------------ ↑↑ 代表此时数组已总体有序)
数组此时已总体有序: 10 20 30 40 50 (数组此时已总体有序)
-----------------------
复制代码
OK 逻辑捋的差很少了咱们开始撸代码,以 Java 为例,咱们先来撸个为整数数组选择排序的递归实现版本:post
/** * @see: 选择排序的递归实现 * @param array: 待排序数组,咱们采用原地排序 * @param start: 当次查找最小值(遍历区间)的初始下标,初次调用值应为0 */
public static void sortSelect(int[] array, int start){
//递归结束条件,此时数组已总体有序
if (start >= array.length - 1){
return;
}
//先假定遍历区间第一个下标的值为最小值;
int minValueIndex = start;
//开始遍历特定数组区间,将区间内最小值交换到区间初始位置
for (int i = start + 1; i <= array.length - 1; i ++){
if (array[i] < array[minValueIndex]){
minValueIndex = i;
}
}
//把最小的值交换到遍历区间初始下标位置
int mid = array[start];
array[start] = array[minValueIndex];
array[minValueIndex] = mid;
//递归开始遍历下个遍历区间
sortSelect(array, start + 1);
}
复制代码
咱们在实际生产环境中写排序算法确定不能用递归,在 Java 中递归的函数调用栈太深会致开销甚大,上面主要是为便于理解来的初级版本,咱们来优化成非递归版本,即双层嵌套版本:优化
/** * @see: 选择排序的非递归实现,即双层嵌套实现 * @param array: 待排序数组,咱们采用原地排序 */
public static void sortSelect(int[] array){
//递归结束条件,此时数组已总体有序
for (int start = 0; start < array.length - 1; start ++){
//先假定遍历区间第一个下标的值为最小值;
int minValueIndex = start;
for (int startInner = start + 1; startInner <= array.length - 1; startInner ++ ){
if (array[startInner] < array[minValueIndex]){
minValueIndex = startInner;
}
}
//把最小的值交换到遍历区间初始下标位置
int mid = array[start];
array[start] = array[minValueIndex];
array[minValueIndex] = mid;
//循环开始遍历下个遍历区间
}
}
复制代码
两种实现代码撸下来,相信你已完全掌握了选择排序算法。spa
选择排序有两个特色:code
选择排序须要的额外空间复杂度同冒泡排序,为О(1)排序
读者请自行发散思惟把以上代码改为为 Comparable 数组排序的版本。递归
下篇咱们聊插入排序。
完。