思路:用一个数组存储待排序的数,每一次都从无序数组中选出一个最大(或者最小)的值放在有序数组的后一个位置。第一趟排序时,整个数组均为无序的数组,将整个数组中最大(或者最小)的元素与数组的第一个元素交换位置,至此完成第一趟排序。此时数组被分成两个数组,前面一部分为有序(只有一个元素),其他部分为无序。往后的每一趟排序均是如此,只不过交换的位置由起始位置变为有序数组的后一个位置,直到排序结束。
遍历总趟数:n-1趟,n为元素个数
每趟的无序元素个数:n-i+1个,i为当前遍历的趟数
java代码实现如下:
package fanzhenhua.sort;
import java.util.Arrays;
//定义一个数据包装类,该类的作用是用来存储待比较的数据,以及为这些数据赋予一些属性,比如:可比较性等
class DataWrap implements Comparable<DataWrap>{
public int data;
public String flag;
public DataWrap(){
}
public DataWrap(int data,String flag){
this.data=data;
this.flag=flag;
}
@Override
public int compareTo(DataWrap data) {
return this.data > data.data ? 1 : (this.data == data.data ? 0 : -1);
}
public String toString(){
return this.data+this.flag;
}
}
public class SelectSort {
//直接选择排序(未优化)
public static void selectSort(DataWrap[] data){
int length=data.length;
DataWrap temp=null;
System.out.println("排序之前为:"+Arrays.toString(data));
for(int i=0;i<length-1;i++){//总共需要进行length-1次排序
for(int j=i+1;j<length;j++){//每次排序都将无序列表中的最小元素放在有序列表的最新一个位置
if(data[i].compareTo(data[j])>0){
temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
System.out.println("第"+i+"排序的结果:"+Arrays.toString(data));
}
System.out.println("排序之后为:"+Arrays.toString(data));
}
//直接选择排序(优化过)
public static void selectSort2(DataWrap[] data){
/*
* 从上面的第一个方法来看我们可以发现,在比较的过程中,每次比较都可能要移动元素,但是每一轮的
* 比较总只有一次移动是有效的,即我们可以在每一轮的比较中只移动一次元素来达到排序的目的
* */
int index=0;
DataWrap temp=null;
int length=data.length;
System.out.println("排序之前为:"+Arrays.toString(data));
for(int i=0;i<length-1;i++){
index=i;//初始化index的值为无序表的第一个元素的位置,
for(int j=i+1;j<length;j++){
//这里必须注意的是,每次比较都要将当轮比较的最小值来进行下一轮比较的基准值
//所以这里取data[index]来进行下一轮的比较
if(data[index].compareTo(data[j])>0){
index=j;//每次比较都将index指向当轮比较的最小值
}
}
//每一趟排序后再进行元素的移动,每一趟只移动一次元素
temp=data[i];
data[i]=data[index];
data[index]=temp;
System.out.println("第"+i+"排序的结果:"+Arrays.toString(data));
}
System.out.println("排序之后为:"+Arrays.toString(data));
}
public static void main(String[] args){
DataWrap[] data = {
new DataWrap(21, "")
,new DataWrap(30, "")
,new DataWrap(49, "")
,new DataWrap(30, "*")
,new DataWrap(16, "")
,new DataWrap(9, "")
};
//selectSort(data);
selectSort2(data);
}
}
直接选择排序算法分析:
时间复杂度:O(n2),数据交换的次数最多要n-1次,但比较的次数较多
空间复杂度:空间复杂度仅为O(1),因为需要借助一个辅助变量
是否为稳定排序:直接选择排序是不稳定的排序,因为在排序的过程中,元素A和B的相对位置会变化。