来源百度百科:
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
一.基本思想
选择排序的思想就是冒泡排序的优化,基于冒泡排序每次的比较交换位置,选择排序,每轮只记录最大的元素下标,每轮只交换一次即可.
二.过程
- 设置两个索引,第一个索引index指向第一个数,第二个索引next指向第一个数索引+1
- 比较index和next的元素的大小,所有next小于index就把next的索引保存下来,移动next索引,直接数组最
- 将index和保存的最小的索引交换位置,这样每次最小的数就在了前面
- 重复上面操作,知道index遍历完数组即可
假设数组为arr={44,3,38,5,47}
1:第一趟排序
- 初始化i指向第一个元素,并且minI =i,j初始化i+1
- 通过不断的移动j,并且每次j与minI进行判断,如果j比minI小就把j赋值给minI
- 这样一轮下来,最小的就在minI中,然后交换与i进行交换,这样每次最小的就在最前面
从j到arr.length-1中最小的下标为1,因为1和i交换位置,结果就为{3,44,38,5,47}
2:第二趟排序
- 从下标2-4中找出最小的保存在minI中
- 然后minI与i交换位置
- 结果为{3,5,38,44,47}
第二趟排序结束,整个数组排序完成
三:总结
我们可以从上得出以下结论
- 从给定数组中,第一趟选择arr[0],然后从arr[0] ~ arr[n-1]找到最小值,和arr[0]交换位置
- 第二趟选择arr[1],然后从arr[1] ~ arr[n-1]找到最小值,和arr[1]交换位置
由于我们可以根据上面的结论推出:
第m趟选择arr[m],然后从arr[m] ~ arr[n-1]找到最小值,和arr[m]交换位置.
代码:
/**
* 选择排序
* @param arr 需要排序的数组
*/
public static void selectSort(int[] arr){
int length = arr.length;
if(length <= 1)
return;
for (int i = 0; i < length-1; i++) {
//记录最开始的值
int minIndex = i;
for (int j = i+1; j < length; j++) {
//如果后面有比minIndex小的,就记录下标
if(arr[minIndex] > arr[j]){
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
四:选择排序的优化问题
- 我们在每次开始的时候记录了i的下标,但是有时经过一趟后,i和minIndex并没有发生变化,因为我们可以这样优化:
/**
* 选择排序
* @param arr 需要排序的数组
*/
public static void selectSort(int[] arr){
int length = arr.length;
if(length <= 1)
return;
for (int i = 0; i < length-1; i++) {
//记录最开始的值
int minIndex = i;
for (int j = i+1; j < length; j++) {
//如果后面有比minIndex小的,就记录下标
if(arr[minIndex] > arr[j]){
minIndex = j;
}
}
//如果minIndex和i不相等,则被重新赋值过,交换即可
if(minIndex != i){
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
2.同时获取最大值和最小值,然后分别插入数组的首部和尾部
五:结论
- 选择排序是基于比较的排序
- 选择排序的空间复杂度为O(n^2)
- 选择排序不是稳定的排序
如果文章有错的地方欢迎指正,大家互相交流。