实现
最大堆:父节点的值大于孩子节点
最小堆:父节点的值小于孩子节点
我们可以使用利用最大堆的特性来实现堆排序
- 构建最大堆
- 将无序数组作为初始堆,计算第一个非叶子节点下标 i=(n-2)/2
2.非叶子节i-0进行向下调整
- 将无序数组作为初始堆,计算第一个非叶子节点下标 i=(n-2)/2
- 将堆顶元素与堆尾元素互换,堆大小减一
- 堆顶向下调整
- 重复第二步直到堆只有一个元素
public class HeapSort {
public static void main(String[] args) {
int[] nums= new int[]{1,5,6,4,2,4,9,7,5,1564,12};
Heap heap =new Heap(nums);
heap.sort();
System.out.println(Arrays.toString(nums));
}
//实现一个最大堆
static class Heap{
int[] data;
//最后一个节点下标
int size;
public Heap(int[] nums){
this.data=nums;
size=nums.length-1;
//下沉
for(int i=(size-1)/2;i>=0;i--){
downJust(i);
}
//System.out.println(Arrays.toString(data));
}
//向下调整
private void downJust(int index){
//最后一个叶子节点的位置
int half=(size-1)>>1;
int value = data[index];
while (index<=half){
int temp=(index<<1)+1;
//选出左右孩子大者
int right=temp+1;
if(right<=size&&data[right]>data[temp]){
temp++;
}
if(data[temp]<value)
break;
data[index]=data[temp];
index=temp;
}
data[index]=value;
}
//排序
public void sort(){
while (size>=1){
//将头节点放到尾节点
int temp=data[0];
data[0]=data[size];
data[size]=temp;
size--;
downJust(0);
}
}
}
}
时间复杂度
构建堆需要o(n)的时间复杂度 证明
每次向下调整需要o(log(n))的时间复杂度
所以时间复杂度为o(nlog(n))