数据结构---堆(最大堆)

在这里插入图片描述

堆的特点: 他是用数组保存的,节点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;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_49324123/article/details/114369771