1、基本思想算法
每次从待排记录中选出最小值放在有序记录的末尾。等每个待排元素均被选出后,整个记录排序就完成了。dom
2、实现步骤工具
这里采用双向选择排序,每次从待排记录中选出最大值和最小值,最大值和待排记录的最后一位交换位置,最小值和待排记录的第一位交换位置。测试
注意,交换位置分以下状况:spa
1)最大值在最左边,最小值在最右边。直接将最大值最小值相互交换便可。3d
2)最大值在最左边,最小值在中间。必须先将最大值与最后一位交换,再将最小值与第一位交换。不然会出错,不信就试试。code
3)最大值在中间,最小值在中间。随意谁先交换都行。blog
4)最小值在最右边,最大值在中间。必须先将最小值与第一位交换,再将最大值与最后一位交换。排序
5)最小值在最右边,最大值在最左边。不用交换。get
对于上述5种状况,其实能够简化成以下状况来作。
1、若是max在最左边,
若是min在最右边,二者直接交换
不然,先交换max,再交换min
2、其余状况一概先交换min,再交换max。
max在最左,min在最右这种状况,因为两次交换,等同于没交换,因此不会出现错误。
3、实现代码
测试工具类 点击这里
package sort; import sort.util.*; /* 选择排序思路: 选择待排记录中最小值,放在左边 双向选择,一次遍历中选出最大值放在右边,选出最小值放在左边 时间复杂度:O(n2) 空间复杂度:O(1) 稳定性: 稳定 */ public class SelectSort implements ISort{ public void sort(int[] a) { int n = a.length; for(int i = 0; i < n / 2; i++) { int maxId = i; int minId = i; for(int j = i; j <= n - i - 1; j++) { if(a[j] > a[maxId]) {maxId = j;} if(a[j] < a[minId]) {minId = j;} } //根据maxId的位置走不一样的交换顺序 int t = 0; if(maxId == i){ if(minId == n - 1 - i) { t = a[maxId]; a[maxId] = a[minId]; a[minId] = t; //max和min位于相反的位置上,直接将其交换 }else{ t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t; //max位于最左,先交换max t = a[minId]; a[minId] = a[i]; a[i] = t; //再交换min } }else{ t = a[minId]; a[minId] = a[i]; a[i] = t; //min位于最右和其余状况,先交换min t = a[maxId]; a[maxId] = a[n-1-i]; a[n-1-i] = t; } } } public static void main(String[] args) { int[] array = RandomArrayGenerator.getRandomArray(100 , 30); SortTestHelper.test(new SelectSort() , array); } }
测试结果:
4、总结分析
时间复杂度:O(n2)
空间复杂度:O(1)
选择排序是一种比较直观易懂的排序算法,时间复杂度不理想,但几乎不占空间。下篇将展现选择排序的改进算法 ----- 堆排序。