堆是最有个性的树,他是用数组表示的树。
如下图所示: i 的子节点: 左是 2i+1,右是 2i+2
i 的父节点: (i-1)/2
最大堆的数据结构组成如下:
typedef struct _heap{
int* arr;
int size;//现有的元素个数
int capacity;//堆的最大容量
}heap;
当构建一个堆的对象heap后,其最后一个子结点为(heap.size-1),对应的最后父节点为(heap.size-2)/2
完整的代码实现如下:
#include<Windows.h>
#include<iostream>
using namespace std;
#define DEFAULT_CAPACITY 100
typedef struct _heap {
int* arr;
int size;//当前已存储的元素个数
int capacity;//最大的存储容量
}heap;
bool initHeap(heap &h,int* arr,int size);
void buildHeap(heap &h);
void adjustHeap(heap& h, int i);
int main() {
int arr[] = {4,99,23,35,23,9,1,39,21,324,231,0};
int size = sizeof(arr) / sizeof(arr[0]);
heap heap;
if (initHeap(heap,arr,size)) {
fprintf(stderr, "建最大堆成功!");
}
else {
fprintf(stderr, "建最大堆失败!");
exit(1);
}
cout << "遍历整个最大堆!" << endl;
for (int i = 0; i < heap.size; i++) {
cout << heap.arr[i] << " ";
}
cout << endl;
system("puase");
return 0;
}
bool initHeap(heap& heap, int* arr, int size) {
int sizereal = size > DEFAULT_CAPACITY ? size : DEFAULT_CAPACITY;
heap.arr = new int[sizereal];
if (!heap.arr) return false;
heap.size = 0;
heap.capacity = sizereal;
if (size > 0) {
memcpy(heap.arr, arr, size*sizeof(int));
heap.size = size;
//h.capacity = sizereal;
buildHeap(heap);
}
return true;
}
void buildHeap(heap &heap) {
for (int i = (heap.size-2)/2; i >=0; i--) {//从最后一个父节点开始
adjustHeap(heap, i);
}
}
void adjustHeap(heap &heap, int index) {
/*判断否存在大于当前节点子节点,如果不存在 ,则堆本身是平衡的,
不需要调整;如果存在,则将最大的子节点与之交换,交换后,
如果这个子节点还有子节点,则要继续按照同样的步骤对这个子节点进行调整*/
int cur = heap.arr[index];//当前待调整的结点
int parent, child;
for (parent = index; (parent * 2 + 1) < heap.size; parent = child) {
child = 2 * parent + 1;
if ((child+1)<heap.size && heap.arr[child] < heap.arr[child+1]) {
child ++;
}
if (heap.arr[child] > cur) {
heap.arr[parent] = heap.arr[child];
heap.arr[child] = cur;
}
else {
break;
}
}
}