数据结构之堆
1 堆的特性
- 它是完全二叉树
- 通常用数组来实现 将二叉树的结点按照层序遍历放入数组 如果一个结点的位置为k 则父节点为k/2 左右子节点分别为2k,2k+1
- 每个结点都大于等于它的两个子节点 或者每个结点都小于等于它的两个子节点
2 堆的API设计
3 堆的实现
3.1 上浮算法
private void swim(int k){
//通过循环比较插入元素与其父元素大小
while(k>1){
if(less(k/2,k)){
exch(k/2,k);
}
k=k/2;
}
}
3.2 下沉算法
4 堆排序
public class HeapSort {
private static boolean less(Comparable[] heap,int i,int j){
return heap[i].compareTo(heap[j])<0;
}
private static void exch(Comparable[] heap,int i,int j){
Comparable tmp = heap[i];
heap[i]=heap[j];
heap[j]=tmp;
}
public static void sort(Comparable[] source){
//构建堆
Comparable[] heap = new Comparable[source.length + 1];
creatHeap(source,heap);
//记录未排序元素的元素中最大的索引
int N=heap.length-1;
while (N!=1){
//交换元素
exch(heap,1,N);
N--;
sink(heap,1,N);
}
System.arraycopy(heap,1,source,0,source.length);
}
private static void creatHeap(Comparable[] source,Comparable[] heap){
//把source中的元素拷贝到heap中
System.arraycopy(source,0,heap,1,source.length);
//对堆中的元素做下沉调整
for(int i=(heap.length/2);i>0;i--){
sink(heap,i,heap.length-1);
}
}
private static void sink(Comparable[] heap,int target,int range) {
while (2*target<=range){
int max;
if(2*target+1<=range){
if(less(heap,2*target,2*target+1)){
max=2*target+1;
}else {
max=2*target;
}
}else {
max=2*target;
}
if(!less(heap,target,max)){
break;
}
exch(heap,target,max);
target=max;
}
}
}
4.1 堆构造过程
把原数组数据拷贝到新数组 再从新数组长度的一半处开始往1处遍历,对每一个遍历元素进行下沉操作
4.2 堆排序复杂度分析
}
}
### 4.1 堆构造过程
把原数组数据拷贝到新数组 再从新数组长度的一半处开始往1处遍历,对每一个遍历元素进行下沉操作
### 4.2 堆排序复杂度分析
堆排序主要有两步组成 首先我们得初始化堆 时间复杂度为O(n) 时间复杂度与树的高度有关 然后我们排序重建堆O(nlogn)所以总的时间复杂度为O(nlogn)空间复杂度为O(2n)因为在初始化堆时需要创建一个同样大小的数组