先来看直接选择排序:
直接选择排序基本思想是:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的 数据元素排完 。
直接选择排序特性:
1丶时间复杂度:O(N^2)
2丶空间复杂度:O(1)
3丶稳定性:不稳定
下面是代码实现:
public static void selectSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) {
int temp = 0;
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
下面是测试类代码:
public static void main(String[] args) {
int[] array = {7,4,5,9,8,2,1};
selectSort(array);
System.out.println(Arrays.toString(array));
结果如下:
堆排序:
基本思想:
堆排序是对直接选择排序的改进
特性:
1丶时间复杂度:O(N*logN)
2丶空间复杂度:O(1)
3丶稳定性:不稳定
堆排序分别有大顶堆和小顶堆:
代码实现:
public static void adjust(int[] array,int start,int end){
int temp = array[start];
for (int i = 2*start+1; i <= end ; i = i*2+1) {
//先找到左右孩子的最大值下标
if(i<end && array[i]<array[i+1]){
i++;//找到了左右孩子最大值
}
if(array[i]>temp){
array[start] = array[i];
start = i;
}else if(array[i]<temp){
//array[start] = temp;
break;
}
}
array[start] = temp;
}
//堆排序
public static void heapSort(int[] array){
for (int i = (array.length-1-1)/2; i >=0 ; i--) {
adjust(array,i,array.length-1);//log2n
}
//整棵树调整为大根堆的时间复杂度?==》nlog2n
//交换
for (int j = 0; j <array.length-1 ; j++) {
int temp = array[array.length-1-j];
array[array.length-1-j] = array[0];
array[0] = temp;
//array.length-1-j-1 第二个-1是因为最后一个已经排好序,
// 交换过不需要再调整
adjust(array,0, array.length-1-j-1);
}
}
结果如下:
这里有个常见的面试题分享给大家:
问:整棵树调整为大根堆的时间复杂度是多少?
答:O(nlogn)
解析:堆排序是一种选择排序,整体主要由构建初始堆+交换堆顶元素和末尾元素并重建堆两部分组成。其中构建初始堆经推导复杂度为O(n),在交换并重建堆的过程中,需交换n-1次,而重建堆的过程中,根据完全二叉树的性质,[log2(n-1),log2(n-2)…1]逐步递减,近似为nlogn。所以堆排序时间复杂度一般认为就是O(nlogn)级。
以上就是直接排序和堆排序的详解。