堆找父子节点与简单代码

最大堆

一、最大堆的特点

1、每个节点最多可以有两个节点
2、根节点的键值是所有堆节点键值的最大值,并所有节点的值都比子节点大
3、处跟节点和最后一个左子节点外,其它节点必须有兄弟节点

二、怎么找子节点或父节点

堆是用数组表示的树
在这里插入图片描述

三、代码

#include<iostream>

#define MAX_CAPCITY 128

typedef struct _Heap {
	int* arr;//存堆元素的数组
	int size;//当前元素个数
	int capacity;//当前存储容量
}Heap;

bool PopHeap(Heap& heap, int& value);//最大元素依次出列
bool insert(Heap& heap, int value);//插入元素
bool initHeap(Heap& heap, int* orginal, int size);//初始化

static void buildHeap(Heap& heap);//循环找节点
static void adjustDown(Heap& heap, int index);//向下排序
static void adjustUp(Heap& heap, int value);//向上排序

//初始化堆
bool initHeap(Heap& heap, int* orginal, int size) {
	int capacity = MAX_CAPCITY > size ? MAX_CAPCITY : size;//看哪个大使用最大容量

	heap.arr = new int[capacity];
	if (!heap.arr)return false;

	heap.capacity = capacity;
	heap.size = 0;

	if (size > 0) {
	//方式一、一起拷贝
		memcpy(heap.arr, orginal, size * sizeof(int));
		heap.size = size;

		//方式二: 一次插入一个
		//for(int i=0; i<size; i++){
		//insert(heap, orginal[i]);
			//}

		buildHeap(heap);
	}
	else {
		heap.size = 0;
	}
	return true;
}

//按照当前的节点和子节点调整成最大堆
void adjustDown(Heap& heap, int index) {
	int cur = heap.arr[index];
	int parend, child;

//根据节点大小判断是否要进行调整
	for (parend = index; (parend * 2 + 1) < heap.size; parend = child) {
		child = parend * 2 + 1;

		//取两个子节点中的最大节点
		if (((child + 1) < heap.size) && (heap.arr[child] < heap.arr[child + 1])) {
		child++;
		}

		//判断当前节点是否大于父节点
		if (cur >= heap.arr[child]) {
			break;
		}
		else {//大于当前父节点,进行交换,子节点位置继续往下调
			heap.arr[parend] = heap.arr[child];
			heap.arr[child] = cur;
		}
	}
}

void buildHeap(Heap& heap) {
	int i;
	for (i = heap.size/2 - 1; i >= 0; i--) {
		adjustDown(heap, i);
	}
}

//最大元素依次出列
bool PopHeap(Heap& heap, int& value) {
	if (heap.size < 1)return false;

	value = heap.arr[0];//对顶最大值给value
	heap.arr[0] = heap.arr[--heap.size];//将最后一个元素给堆顶,并数组减1

	adjustDown(heap, 0);//重新排序
	return true;
}

bool insert(Heap& heap, int value) {
	if (heap.size == heap.capacity) {//判断是否可以继续插入值
		std::cout << "资源耗尽" << std::endl;
		return false;
	}
	int index = heap.size;//获取到最后一个元素
	heap.arr[heap.size++] = value;//在最后一个元素后加
	adjustUp(heap, index);//重新排序,向上排序
	return true;
}

//向上排序
void adjustUp(Heap& heap, int index) {
	if (index < 0 || index >= heap.size) {
		return;
	}
	while (index > 0) {
		int temp = heap.arr[index];//获取到元素位置
		int parent = (index - 1) / 2;//找到父节点

		if (parent >= 0) {//判断是否有父节点
			if (temp > heap.arr[parent]) {//进行比较
				heap.arr[index] = heap.arr[parent];//重新排序
				heap.arr[parent] = temp;
				index = parent;
			}
			else {//不需要换位置时结束循环
				break;
			}
		}
		else {//没有父节点停止循环
			break;
		}
	}
}

int main() {
	int su[] = { 11,66,55,33,77,88,22,90,44,12 };
	Heap heap;

	if (!initHeap(heap, su, sizeof(su) / sizeof(su[0]))) {
		std::cout << "初始化失败" << std::endl;
		exit(-1);
	}
	for (int i = 0; i < heap.size; i++) {
		std::cout << i<<"\t" << heap.arr[i] << std::endl;
	}
	std::cout << "-----------------------" << std::endl;
	insert(heap, 99);
	for (int i = 0; i < heap.size; i++) {
		std::cout << i << "\t" << heap.arr[i] << std::endl;
	}

	std::cout << "元素从大到小依次出列" << std::endl;
	int value;
	while (PopHeap(heap, value)) {
		std::cout << "出列元素为:" << value << std::endl;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值