1.原理
对于待排序数组,在遍历过程中使用k记录第j(1 <= j < N-1)小的元素下标,N为数组长度。第一次记录第一小元素的下标,第二次记录第二小元素的下标,依此类推,直至记录到第N-1小元素的下标。遍历完成后调换才进行一次元素互换。
2.实例
待排序数组:[3,4,1,5,2]
注:k用于存储元素的下标,元素进行两两比较时,没有进行多次换位,而是将较小元素的下标存于k中,当所有未排序的元素进行比较后,k即是最小元素的下标。
第一次外排序: 第二次外排序: 第三次外排序: 第四次外排序:
k=0 k=1 k=2 k=3
3<4 no----k=0; 4>3 yes---k=2; 3<5 no----k=2; 5>4 yes----k=4;
3>1 yes---k=2; 3<5 no----k=2; 3<4 no----k=2; 换值:
1<5 no----k=2; 3>2 yes---k=4; 此时k的值未变,不需要 a3=4,a4=5
1<2 no----k=2; 换值: 换值。 变换后:
换值: a1=2,a4=4; [1,2,3,4,5]
a0=1,a2=3; 变换后:
变换后: [1,2,3,5,4]
[1,4,3,5,2]
3.时间复杂度
在最好的情况下,交换0次,比较(n-1)n/2次,时间复杂度为O(n^2)。
在最坏的情况下,交换3n(n-1)/2次,比较n(n-1)/2次,时间复杂度为O(n^2)。
注:简单选择排序看似和冒泡排序的时间复杂度虽然相同,但是它的性能优于冒泡排序,原因如下:冒泡排序进行关键字的比较时,可能会交换两个记录的值,而简单选择排序只需将最小记录和被比较记录进行交换。即每次外排序时,简单选择排序交换值的次数不大于1,冒泡排序大于等于0。
4.代码
1 public class SelectSortTest { 2 3 //遍历数组 4 public static void Paixu(int a[]){ 5 for(int i=0;i<a.length;i++){ 6 System.out.print(a[i]+" "); 7 } 8 9 System.out.print(); 10 } 11 12 //简单选择排序 13 public static void Test(int a[]){ 14 for(int i=0;i<a.length-1;i++){ //共计n-1次外排序 15 int k=i; //设k的初始值为i 16 for(int j=i+1;j<a.length;j++){ 17 if(a[k]>a[j]){ //ak和后面的元素比较,符合要求则令k=j,直至找到最小元素下标 18 k=j; 19 } 20 } 21 if(k!=i){ //当最小元素下标发生变化时,将两记录换值 22 int temp=a[i]; 23 a[i]=a[k]; 24 a[k]=temp; 25 } 26 27 SelectSortTest.Paixu(a); 28 } 29 } 30 public static void main(String args[]){ 31 int a[]={3,5,1,4,2}; 32 SelectSortTest.Test(a); 33 } 34 }