堆是一棵完全二叉树,是用数组存放的。层序遍历存到数组中,用数组模拟。很有意思、
大顶堆,小顶堆。
5个要点就是 调整,建堆,插入,删除,排序。
时间复杂度O(logn)
1)调整
const int maxn = 100;
int heap[maxn], n = 10;
void downAdjust(int low, int high){
int i = low, j = i * 2;
while( j <= high ){
if( j + 1 <= high && heap[j + 1] > heap[j]){
j = j + 1;
}
if(heap[j] > heap[i]){
swap(heap[i], heap[j]);
i = j;
j = i * 2;
}else{
break;
}
}
}
2)建堆
void createHeap(){
for(int i = n/2; i >= 1; i--){ //O(n) 从n/2处开始调整
downAdjust(i, n);
}
}
3)删除堆顶元素
void deleteTop(){
heap[1] = heap[n--];
downAdjust(1, n); //从头向下调整
}
4)添加元素,我们肯定是添加到数组的末尾,然后进行调整。并且是从这个点开始向上进行调整。向上调整总是把欲调整的结点与父亲的结点比较,如果权值不父亲结点大,那么就交换其与父亲结点,这样反复比较,直到达到堆顶或是父亲结点较大为止(大顶堆)。
时间复杂度O(logn);
void upAdjust(int low, int high){
int i = high, j = i / 2; //i为欲调整(插入)结点,j为其父亲
while(j >= low){
if(heap[j] < heap[i]){
swap(heap[j], heap[i]);
i = j;
j = i / 2;
}else{
break;
}
}
}
void insert(int x){
heap[++n] = x;
upAdjust(1, n);
}
5)堆排序
void heapSort(){
createHeap(); // 建堆
for(int i = n; i > 1; i--){
swap(heap[i], heap[1]); //交换i 与堆顶位置,
downAdjust(1, i - 1); //调整堆
}
}