原理
刚开始整个数组是无序区间,在无序区间找到最大的元素,将最大元素放在数组的最后,第二次在无序区间查找最大元素,找到最大的,放入数组的倒数第二个,依此类推;或者是在无序区间找最小元素,将最小元素放在数组开始,第二次在无序区间找的最小元素放在第二位置,依此类推
实现
//最大元素放在最末尾
public void selectSort(int[] arr){
//无序区间:[0,arr.length-i)
//有序区间:[arr.length-i,arr.length)
// i 遍历的是数组需要排多少次序能达到有序
for(int i = 0;i <arr.length-1;i++){
int max = 0;
//j 遍历的是无序区间,在无序区间中找最大
for(int j = 0;j < arr.length-i;j++){
if(arr[j]>arr[max]){
max = j;
}
}
swap(arr,max,arr.length-i-1);
}
}
private void swap(int[] arr, int max, int i) {
int t = arr[max];
arr[max] = arr[i];
arr[i] = t;
}
//最小的放最前面
public static void selectSort1(int[] arr){
//无序区间:[i,arr.length)
//有序区间[0,i)
for(int i = 0;i <arr.length-1;i++){
int min = i;
for(int j = i+1;j<arr.length;j++){
if(arr[j]<arr[min]){
min = j;
}
}
swap(arr,min,i);
}
}
private void swap(int[] arr, int max, int i) {
int t = arr[max];
arr[max] = arr[i];
arr[i] = t;
}
//将无序区间最大的元素放在最尾,最小的元素放在最开始,是以上两种的结合
public static void selectSort2(int[] arr){
//无序区间:[begin,end]
int begin = 0;
int end = arr.length-1;
while(begin<end){
int max = 0;
int min = 0;
for(int j = begin+1;j<=end;j++){
if(arr[j]>arr[max]){
max = j;
}
if(arr[j]<min){
min = j;
}
}
swap(arr.min,begin);
if(max==begin){
max = min;
}
swap(arr,max,end);
begin++;
end--;
}
}
复杂度
稳定性
不稳定,当存在重复元素时,会先将第一个元素放到后面,再将重复的第二个元素放到倒数第二,不能保证稳定性
如下图,交换前红色的 4 在前,蓝色在后,交换后,蓝色在前,红色在后