堆的特点: 他是用数组保存的,节点i,
i的子节点左:2i+1,i的右子节点:2i+2
i的父节点:(i-1)/2
最大堆特点:
1.每个节点最多可以有两个节点
2.根节点的值是所有节点中最大的值,且每个节点的值都比其孩子节点大
3.除了根节点没有兄弟外,最后一个左子节点可以没有兄弟节点,其他节点必须有兄弟节点。
堆的结构:用来装数据的数组(指针),数组数据有几个,数据的最大长度
typedef struct Heap{
int* arr;
int size;
int max_length;
}Heap;
初始化和建立堆:
初始化:将结构体中的数据先进行初始化,再利用地址拷贝函数,将未排序数据的数组拷贝到结构体的组数中,再建立堆。
建立堆:根据堆的特性,从最后一个父节点开始遍历,每个父节点与其下的两个比较,最终得到堆
adjustDown()函数:将给的节点位置放到parent中,因为父节点下的子节点,也可以有孙节点,所以利用特性+循环判断,是否有子节点下还有子节点,循环里面先得到左子节点,再判断左右子节点谁大,大的那一个与父节点进行比较,如果大于父节点,就交换。
bool init(Heap& heap, int* arry, int size) {
heap.max_length = MAX_LENGTH;
heap.arr = new int[heap.max_length];
if (!heap.arr) return false;
heap.size = 0;
if (size > 0) {
memcpy(heap.arr, arry, size * sizeof(int));
heap.size = size;
Build_Heap(heap);
}
return true;
}
void Build_Heap(Heap& heap) {
for (int i = (heap.size / 2) - 1;i >= 0;i--) {
adjustDown(heap, i);
}
}
void adjustDown(Heap& heap, int index) {
int tmp = heap.arr[index];
int child, parent;
for (parent = index;parent * 2 + 1 < heap.size;parent = child) {
child = parent * 2 + 1;
if ((child + 1) < heap.size && heap.arr[child] < heap.arr[child + 1]) {
child++;
}
if (tmp < heap.arr[child]) {
heap.arr[parent] = heap.arr[child];
heap.arr[child] = tmp;
}
else {
break;
}
}
}
插入数据:
先将数据插到堆的最后,再利用adjustUp()来调节
adjustUp():因为堆只需要父节点比旗下的子节点大就行,所以不需要比较全部,只需要比较自己的父节点,利用堆的特性:
父节点(i-1)/2;如果插入的节点比自己的父节点大,就交换,并继续向上比较,如果一开始就不大于自己的节点,就无需再比较。
bool insert(Heap& heap, int data) {
if (heap.size == heap.max_length) {
cout << "空间已满" << endl;
return false;
}
int index = heap.size;
heap.arr[heap.size++] = data;
adjustUp(heap, index);
return true;
}
void adjustUp(Heap& heap, int index) {
int tmp;
int child, parent;
child = index;
while (child > 0) {
tmp = heap.arr[child];
parent = (child - 1) / 2;
if (heap.arr[parent] < heap.arr[child]) {
heap.arr[child] = heap.arr[parent];
heap.arr[parent] = tmp;
child = parent;
}
else {
break;
}
}
}
获取根节点元素:
将根节点元素取出,放到一个变量中,并将堆中的最后一个元素放到根节点出,在对根节点进行向下调整。
bool popMAX(Heap& heap, int& value) {
if (heap.size == 0) {
cout << "堆为空" << endl;
return false;
}
value = heap.arr[0];
heap.arr[0] = heap.arr[--heap.size];
adjustDown(heap,0);
return true;
}
全部代码:
#include<iostream>
#include<Windows.h>
#define MAX_LENGTH 100
using namespace std;
typedef struct Heap{
int* arr;
int size;
int max_length;
}Heap;
bool init(Heap& heap, int* arry, int size);
bool popMAX(Heap &heap,int &value);
bool insert(Heap& heap, int data);
void Build_Heap(Heap& heap);
void adjustDown(Heap& heap, int index);
void adjustUp(Heap &heap,int index);
int main() {
Heap heap;
int arry[] = {
1, 2, 3, 87, 93, 82, 92, 86, 95 };
//堆的初始化
if (!init(heap, arry, sizeof(arry) / sizeof(arry[0]))) {
cout << "初始化失败" << endl;
}
for (int i = 0; i < heap.size; i++) {
printf("the %dth element:%d\n", i, heap.arr[i]);
}
//堆中插入元素
insert(heap,99);
printf("队中插入99后:\n");
for (int i = 0; i < heap.size; i++) {
printf("the %dth element:%d\n", i, heap.arr[i]);
}
//取出队中最大值
int value;
cout << "取出数来" << endl;
while (popMAX(heap, value)) {
cout << value << endl;
}
system("pause");
return 0;
}
bool init(Heap& heap, int* arry, int size) {
heap.max_length = MAX_LENGTH;
heap.arr = new int[heap.max_length];
if (!heap.arr) return false;
heap.size = 0;
if (size > 0) {
memcpy(heap.arr, arry, size * sizeof(int));
heap.size = size;
Build_Heap(heap);
}
return true;
}
void Build_Heap(Heap& heap) {
for (int i = (heap.size / 2) - 1;i >= 0;i--) {
adjustDown(heap, i);
}
}
void adjustDown(Heap& heap, int index) {
int tmp = heap.arr[index];
int child, parent;
for (parent = index;parent * 2 + 1 < heap.size;parent = child) {
child = parent * 2 + 1;
if ((child + 1) < heap.size && heap.arr[child] < heap.arr[child + 1]) {
child++;
}
if (tmp < heap.arr[child]) {
heap.arr[parent] = heap.arr[child];
heap.arr[child] = tmp;
}
else {
break;
}
}
}
bool insert(Heap& heap, int data) {
if (heap.size == heap.max_length) {
cout << "空间已满" << endl;
return false;
}
int index = heap.size;
heap.arr[heap.size++] = data;
adjustUp(heap, index);
return true;
}
void adjustUp(Heap& heap, int index) {
int tmp;
int child, parent;
child = index;
while (child > 0) {
tmp = heap.arr[child];
parent = (child - 1) / 2;
if (heap.arr[parent] < heap.arr[child]) {
heap.arr[child] = heap.arr[parent];
heap.arr[parent] = tmp;
child = parent;
}
else {
break;
}
}
}
bool popMAX(Heap& heap, int& value) {
if (heap.size == 0) {
cout << "堆为空" << endl;
return false;
}
value = heap.arr[0];
heap.arr[0] = heap.arr[--heap.size];
adjustDown(heap,0);
return true;
}