什么是堆
堆就是一种特殊的二叉树,他有以下特点:
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。
堆又可以分为大根堆和小根堆
大根堆:根节点最大,每个节点都小于或等于父节点
小跟堆:根节点最小,每个节点都大于或等于父节点
堆的建立思想
以大根堆为例,每一个节点都当作是一个大根堆,我们通过维护每一个节点的堆结构进而将整个二叉树变成堆。由于叶子节点没有子节点,所有不需要对他维护。
代码实现
java
//这里用数组来代替堆结构
public void buildMapHeap(int []heap,int heapSize){
//遍历没一个非叶子节点
for(int i=(heapSize)/2-1;i>=0;i--){
maxHeapify(heap,i,heapSize);
}
}
public void maxHeapify(int []heap,int i,int heapSize){
//左孩子索引
int l=2*i+1;
int r=2*i+2;
//假设最大值的索引是父节点
int maxVlue=i;
if(l<heapSize&&heap[l]>heap[maxVlue]){ //(叶子节点不需要调整)&&()
maxVlue=l;
}
if(r<heapSize&&heap[r]>heap[maxVlue]){ //(叶子节点不需要调整)&&()
maxVlue=r;
}
if(maxVlue!=i){
//交换让父节点值最大
swap(heap,i,maxVlue);
//由于调整的堆结构可能导致原来的子节点的堆结构发生改变
//所有也要调整原来子节点的堆结构
maxHeapify(heap,maxVlue,heapSize);
}
}
public void swap(int heap[],int i,int j){
int t=heap[i];
heap[i]=heap[j];
heap[j]=t;
}
小根堆代码实现类似不在赘述 大家可以自己实现。
建立好大根堆后,堆顶就是数组里面最大的元素,如果要实现堆排序只需要每次移除这个堆顶元素,然后将堆尾元素替换,再重新以堆顶进行调整。