算法简介
简单选择排序是一种选择排序。
选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。
白话理解
依然已排队为例,在排队时,有的老师可能会选择这样排序,先在一列中选出最矮的,放在第一位,然后选出第二矮的,放在第二位。队伍完成排序。而这就是选择排序的思想。
简单排序处理流程
(1)从待排序序列中,找到关键字最小的元素;
(2)如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
(3)从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
Java代码实现:
1 package sortDemo; 2 3 /** 4 * 插入代码实现 5 * @author xianyu 6 * @CreatTime 下午8:16:11 7 */ 8 public class SelectionDemo { 9 10 public static void main(String[] args) { 11 int[] sort ={3,2,1,4,6,5,8,9,10,7} ; 12 System.out.println("排序前:"); 13 print(sort); 14 selectionDemo(sort); 15 System.out.println(" 排序后:"); 16 print(sort); 17 } 18 19 public static void selectionDemo(int[] a){ 20 for (int i = 0; i < a.length; i++) { 21 for (int j = i+1; j < a.length; j++) { 22 if(a[j]<a[i]){ 23 int tmp = a[j]; 24 a[j] = a[i]; 25 a[i]=tmp; 26 } 27 } 28 } 29 } 30 31 public static void print(int[] a){ 32 for (int i = 0; i < a.length; i++) { 33 System.out.print(a[i]+" "); 34 } 35 } 36 }
算法分析:
时间复杂度
简单选择排序的比较次数与序列的初始排序无关。 假设待排序的序列有 N 个元素,则比较次数总是N (N - 1) / 2。
而移动次数与序列的初始排序有关。当序列正序时,移动次数最少,为 0.
当序列反序时,移动次数最多,为3N (N - 1) / 2。
所以,综合以上,简单排序的时间复杂度为 O(N2)。
空间复杂度
简单选择排序需要占用 1 个临时空间,在交换数值时使用。
由交换条件,a[j+1]<a[i]可以判断出,相同的值并不会交换。所以简单选择排序是稳定排序。
简单选择排序的改进——二元选择排序
简单选择排序,每趟循环只能确定一个元素排序后的定位。我们可以考虑改进为每趟循环确定两个元素(当前趟最大和最小记录)的位置,从而减少排序所需的循环次数。改进后对n个数据进行排序,最多只需进行[n/2]趟循环即可。具体实现如下:
1 static void selectSort(int[] r) { 2 int n = r.length; 3 int i ,j , min ,max, tmp; 4 for (i=0 ;i <= n/2;i++) { 5 // 做不超过n/2趟选择排序 6 min = i; max = i ; //分别记录最大和最小关键字记录位置 7 for (j= i+1; j<= n-1-i; j++) { 8 if (r[j] > r[max]) { 9 max = j ; continue ; 10 } 11 if (r[j]< r[min]) { 12 min = j ; 13 } 14 } 15 //该交换操作还可分情况讨论以提高效率 16 tmp = r[i]; r[i] = r[min]; r[min] = tmp; 17 tmp = r[n-1-i]; r[n-1-i] = r[max]; r[max] = tmp; 18 } 19 }