目录
1.直接选择排序
每次从无序区间选出最大/最小的一个元素,存放在无序区间的最后/最前面,直到全部待排序的数据元素排完。一趟下来只有一个元素到达最终位置。
/**
* 直接选择排序 不稳定的排序算法
* @param arr
*/
//排序是一个工具,我们都用static静态方法
public static void selectionSort(int[] arr) {
//每次从待排序数组中选择最小值放在待排序数组的最前面
//最外层的for循环表示要执行的总次数,类似于冒泡,当剩下最后一趟时,整个数组已经有序
//默认第一个元素就是有序的
//已经有序的集合[0,i)
//待排序的集合[i+1,n)
//每次进行一趟排序,最小值就放在了数组的最前面,已经有序的集合元素个数 + 1
//待排序集合元素个数 - 1
for(int i = 0; i < arr.length - 1; i++) {
//min变量存储了最小值元素的下标
int min = i;
//每次从无序区间中选择最小值
for(int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
//此时min就存储了最小值的元素下标,就把min对应的元素换到无序区间的最前面
swap(arr, i, min);
}
}
/**
* 交换操作
* @param arr
* @param i
* @param j
*/
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
稳定性:不稳定。
时间复杂度:O(n^2)
2.up↑——双向选择排序
每次从无序区间选出最小值和最大值元素,分别存放在无序区间的最前面和最后面,直到全部待排序的数据元素排完。一趟下来有2个元素到达了最终位置,理论上比直接选择排序快了一倍左右。
/**
* 双向选择排序
* 每次选出最小值放前面,最大值放后面
* @param arr
*/
public static void selectionSortOP(int[] arr) {
int low = 0, high = arr.length - 1;
//有序区间[0, low + 1)
//用<,无序区间只剩一个元素,当low==high时,直接跳出循环,不用走下面的判断
while(low < high) {
int min = low, max = low;
for(int i = low + 1; i <= high; i++) {
if (arr[i] > arr[max]) {
max = i;
}
if(arr[i] < arr[min]) {
min = i;
}
}
//min存储了无序区间的最小值,max存储了无序区间的最大值
swap(arr, low, min);
if(max == low) {
//当max就处在low的位置,由于swap(arr,low,min),low对应的元素值修改了,修改到min对应的下标
//(相当于将min和max这俩下标对应的值交换了,其下标也要进行交换)
max = min;
}
swap(arr, max, high);
low += 1;
high -= 1;
}
}
稳定性:不稳定