20200124 之农历新春佳节的除夕,看到此博客者鼠年吉祥如意,发大财! 数据结构和算法的构建最大堆

堆是最有个性的树,他是用数组表示的树。
如下图所示: 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;
		}
	}
			
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值