基本原理
选择排序的简单原理:选择排序算法通过从未排序部分重复查找最小元素(考虑升序)并将其放在开头来对数组进行排序。
将数组两个子数组:
- 已排序子数组
- 未排序子数组
选择排序中每次循环都会从未排序子数组中选取最小元素放入已排序子数组
小例子
排序数组:[2,3,6,2,7,5,1,4]
第一次循环:
将[2,3,6,2,7,5,1,4]中最小元素,放到开头
结果:[1,3,6,2,7,5,2,4]
第二次循环:
将[3,6,2,7,5,2,4]中最小元素,放到开头
结果:[1,2,6,3,7,5,2,4]
第三次循环:
将[6,3,7,5,2,4]中的最小元素,放到开头
结果:[1,2,2,3,7,5,6,4]
第四次循环:
将[3,7,5,6,4]中的最小元素,放到开头
结果:[1,2,2,3,7,5,6,4]
第五次循环:
将[7,5,6,4]中的最小元素,放到开头
结果:[1,2,2,3,4,5,6,7]
第六次循环:
将[5,6,7]中的最小元素,放到开头
结果:[1,2,2,3,4,5,6,7]
...
最后排序结果:[1,2,2,3,4,5,6,7]
有序子数组不断扩大,无序子数组不断缩小,最终整个数组都是有序数组
代码实现Java
public static int[] Sort(int[] array){ //记录数组长度 int length = array.length; //外层循环 for (int i=0;i<length-1;i++){ //将最小数下标记录为i int min_index = i; //内层循序 遍历i后边的数组 for (int j=i+1;j<length;j++){ if (array[j]<array[min_index]){ //如果当前遍历到的数小于当前最小索引的对应的值 //将当前的索引赋值给最小索引 min_index = j; } }//内层循环 end //交换i对应值和最小索引对应的值 int temp = array[min_index]; array[min_index] = array[i]; array[i] = temp; }//外层循环end return array; }
算法分析
- 时间复杂度:
O(n^2) - 比较次数
n(n-1)/2 - 交换次数
n-1
选择排序是不稳定的
看下面例子,按照选择排序进行排序:
![](https://www.eimg.top/images/2020/03/31/99a3b662dee5aa34a7f371b32e46ef43.png)
可以看到,在第一次循环时,两个2 的相对位置就已经发生了改变,显然,选择排序是不稳定的。
完整代码(含排序步骤输出)
public class SelectionSort { public static void main(String[] args) { int[] arr = {2,3,6,2,7,5,1,4}; System.out.println("原数组:--------------"); for (int i : arr) { System.out.print(i+" "); } System.out.println(); int[] arr2 = SortDetail(arr); System.out.println("排序后数组:----------"); for (int i : arr2) { System.out.print(i +" "); } } public static int[] Sort(int[] array){ //记录数组长度 int length = array.length; //外层循环 for (int i=0;i<length-1;i++){ //将最小数下标记录为i int min_index = i; //内层循序 遍历i后边的数组 for (int j=i+1;j<length;j++){ if (array[j]<array[min_index]){ //如果当前遍历到的数小于当前最小索引的对应的值 //将当前的索引赋值给最小索引 min_index = j; } }//内层循环 end //交换i对应值和最小索引对应的值 int temp = array[min_index]; array[min_index] = array[i]; array[i] = temp; }//外层循环end return array; } public static int[] SortDetail(int[] array){ //记录数组长度 int length = array.length; //外层循环 for (int i=0;i<length-1;i++){ //将最小数下标记录为i int min_index = i; System.out.println("----------------------------------------"); System.out.println("第"+(i+1)+"次内层循环(min_index=i="+i+";初始min_index的值:"+array[min_index]+")"); //内层循序 遍历i后边的数组 for (int j=i+1;j<length;j++){ if (array[j]<array[min_index]){ //如果当前遍历到的数小于当前最小索引的对应的值 //将当前的索引赋值给最小索引 min_index = j; } }//内层循环 end System.out.println("内层完成循环的最小索引是:"+min_index + "对应的值为:"+array[min_index]); //交换i对应值和最小索引对应的值 int temp = array[min_index]; array[min_index] = array[i]; array[i] = temp; for (int i1 : array) { System.out.print(i1+" "); } System.out.println(); }//外层循环end return array; } }
来源:https://www.cnblogs.com/erkye/p/12376996.html