原理:比较+交换
选择排序就是冒泡排序的优化。选择排序就是在每一趟的排序中选择一个最大的数放在最后或者选择最小的数放在最前边。选择排序两个交换的数当中至少有一个数可以 交换到最终的位置上。直到所有的元素都排序完,排序结束。
算法描述:(以升序为例)
1)如果是一个有n个数的序列,一共有n-1次排序。
2)在每第一趟中挑选最大的数放到最后,即先假设当前数为最大的数,然后一次和后边的数进行比较,如发现后边的数比当前的数大就重新确定最大数,并且得到最大数的下标
3)继续对前边的n-1个数继续进行排序,挑选最大的数字放在n-1的位置上
3)重读第二步,直到所有的元素都排序完成的时候,排序完成
举例:
原始的数组 :101, 34,119,1
第一轮排序 : 101,34,1,119 (1和119交换)
第二轮排序 : 1,34,101,119 (1和101交换)
第三轮排序 : 1,34,101,119 (34在他本身的位置不要交换)
基本方法:两层循环,外层决定排序的趟数,内层去寻找每一趟的最大的数字,然后交换两数。
//记录一个数
public static void SelectSort(int[] array){
for (int i = 0; i <array.length-1 ; i++) {//排序的趟数
int maxindex=i;//记录最小值的位置
int max=array[i];//记录最小值
for (int j = i+1; j <array.length; j++) {//找到最大值进行交换
//如果改为max<array[j]:就是把最大的放在最前边排序
if(max>array[j]){//说明后一个数比前一个数大
maxindex=j;//重置min
max=array[j];//重置minindex
}
}
if(maxindex!=i){//如果最大的数,没有在对应的位置才进行交换
array[maxindex]=array[i];
array[i]=max;
}
}
}
//记录两个数
public static void SelectSort(int[] array){
for (int i = 0; i <array.length-1 ; i++) {//排序的趟数
int maxindex=i;//记录最小值的位置
int max=array[i];//记录最小值
for (int j = i+1; j <array.length; j++) {//找到最大值进行交换
//如果改为max<array[j]:就是把最大的放在最前边排序
if(max>array[j]){//说明后一个数比前一个数大
maxindex=j;//重置min
max=array[j];//重置minindex
}
}
if(maxindex!=i){//如果最大的数,没有在对应的位置才进行交换
array[maxindex]=array[i];
array[i]=max;
}
}
}
选择排序的优化:主要和数据移动有关,如果一个数字他与移动的位置的数相等,就不移动
优化:在找最大值得同时,也找最小值,这样可以减少排序的趟数。
public static void selectSort2(int[] arr,int len){
for(int i=0;i<len/2;i++){//排序的趟数
int max=i;//记录最大值得下标
int min=i;
for(int j=1+i;j<len-i-1;j++){//比较元素的次数,左边+,右边-
if(arr[max]<arr[j]){
max=j;
}
if(arr[min]>arr[j]){
min=j;
}
}
if(arr[max]!=arr[len-i-1]){//如果最大的数,没有在对应的位置才进行交换
int tmp=arr[len-i-1];
arr[len-i-1]=arr[max];
arr[max]=tmp;
}
if(arr[min]!=arr[i]){//如果最小的数,没有在其对应的位置才进行交换
int tmp=arr[i];
arr[i]=arr[min];
arr[min]=tmp;
}
}
}
时间复杂度:
因为就算元素都是有序的,选择排序也需要n2/2来确认元素是有序的。
稳定性:
选择排序是不稳定的,它会改变相同元素的相对顺序。