一、选择排序
在无序区间中:
每次选择最大的放在后面
或者
每次选择最小的放在前面
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
/**
* 【选择排序】---每次选择最大的放在后面
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* 稳定性:不稳定
* @param array
*/
public static void selectSort(int[] array){
//一共多少次选择过程
for(int i = 0;i < array.length-1;i++){
//无序区间:[0 , array.length-i)
//有序区间:[array.length-i , array.length)
int maxIndex = 0;
for(int j = 1 ; j < array.length - i; j++){
if(array[j] > array[maxIndex]){
maxIndex = j;
}
}
//找出无序区间最大数的下标,然后与无序区间最后一个交换
int temp = array[maxIndex];
array[maxIndex] = array[array.length-i-1];
array[array.length-i-1] = temp;
}
}
/**
* 【选择排序】---每次选择最小的放在前面
* 时间复杂度:O(n^2)
* 空间复杂度:O(1)
* 稳定性:不稳定
* @param array
*/
public static void selectSort1(int[] array) {
for(int i = 0;i<array.length;i++){//可以写成 i<array.length-1
//有序区间:[0,i)
//无序区间:[i,array.length)
for(int j = i+1;j<array.length;j++){
if(array[j] < array[i]){
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
二、双向选择排序(选择排序的变形)
三、堆排序
基本原理也是选择排序,只是不使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的数。
- eg:从小到大排序 —> 建大堆
- !排正序不能用小堆,会发生堆顶元素没了(逆序用小堆
时间复杂度:O(n*logn)
空间复杂度:O(1)
稳定性:不稳定
/**
* 时间复杂度:O(n*logn)
* n*logn + n * (1+log(n))
*
* 空间复杂度:O(1)
* 稳定性:不稳定
* @param array
*/
public static void heapSort(int[] array){
//1.建大堆
createBigHeap(array);
//2.进行选择的过程,一共需要array.length-1组
for(int i = 0;i<array.length-1;i++){
//无序区间:[0,array.length-i)
swap(array,0,array.length-i-1);
//无序区间:[0,array.length-i-1) 少了一个:因为把那个大的换下去了
adjustDown(array,array.length-i-1,0);
}
}
public static void adjustDown(int[] array,int size,int index){
while (2 * index + 1 < size){
int maxChildIndex = 2 * index +1;//最大的孩子下标
if(maxChildIndex + 1 < size && array[maxChildIndex+1] > array[maxChildIndex]){
maxChildIndex++;
}
if(array[index] >= array[maxChildIndex]){
break;
}
swap(array,index,maxChildIndex);
index = maxChildIndex;
}
}
//建堆
public static void createBigHeap(int[] array){
for(int i = (array.length-1-1)/2; i >=0;i--){
adjustDown(array,array.length,i);
}
}
public static void swap(int[] array,int l,int r){
int tmp = array[l];
array[l] = array[r];
array[r] = tmp;
}