代码
[3, 1, 5, 7, 2, 4, 9, 6]--把全部的最小的数(1)的和第 1 个数(3)交换位置 [1, 3, 5, 7, 2, 4, 9, 6]--把余下的最小的数(2)的和第 2 个数(3)交换位置 [1, 2, 5, 7, 3, 4, 9, 6]--把余下的最小的数(3)的和第 3 个数(5)交换位置 [1, 2, 3, 7, 5, 4, 9, 6]--把余下的最小的数(4)的和第 4 个数(7)交换位置 第五轮不交换-----把余下的最小的数(5)的和第 5 个数(5)交换位置 [1, 2, 3, 4, 5, 7, 9, 6]--把余下的最小的数(6)的和第 6 个数(7)交换位置 [1, 2, 3, 4, 5, 6, 9, 7]--把余下的最小的数(7)的和第 7 个数(9)交换位置 [1, 2, 3, 4, 5, 6, 7, 9]--完成了
public class Test { public static void main(String[] args) throws Exception { int[] arr = { 3,1,5,7,2,4,9,6 }; System.out.println(Arrays.toString(arr)); selectSort(arr); } /** * 选择排序 */ public static void selectSort(int[] a) { int minIndex = 0;//用来记录(剩余数中的)最小值的下标 for (int i = 0; i < a.length; i++) {//这里的判断条件严格来说为【i < a.length-1】,不过宽松一点也没关系,因为后面还会做边界判断的 minIndex = i;//每次都是从 i 开始遍历的 for (int j = i + 1; j < a.length; j++) { if ((a[j] < a[minIndex])) minIndex = j;//(在剩余数中)找到最小值并保存其下标 } swap(a, i, minIndex);//将查到的最小值元素和第 i 个元素交换 } } public static void swap(int[] arr, int i, int j) { if (i == j) return; int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; System.out.println(Arrays.toString(arr)); } }
简介
白哥解释: 选择排序过程:第 n 轮时是将第 n 个数和后面每一个数进行比较,如果第 m 个数比第 n 个数小,就记录第 m 个数的位置,然后继续拿第 m 个数和后面每一个数进行比较,直到结尾;一共排了 a.length 轮,第 n 轮排序的结果是把最 n 小数的和第 n 个数交换位置。 第 n 轮比较次数为 a.length-n,每一轮交换次数都是 0或1 ,共排序 m=a.length 轮 所以共比较 (m)+(m-1)+(m-2)+……+2+1=m(m-1)/2 次,共交换 m 次(最多),总的时间复杂度为O(m^2)+O(m)=O(m^2)
过程: 对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小,则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较,如果后面的元素比他要小,则用变量k记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小的数了。然后找到数组中第二小的数,让他跟数组中第二个元素交换一下值,以此类推。
时间复杂度: 选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。 比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。
时间: 2024-11-05 21:49:17