C++-数据结构-堆的原理及代码实现-精选!!!

七龙珠第23界武道大会前八强
在这里插入图片描述
武道大会这种打擂台的比赛就类似与堆的原理 最强的人称为冠军
在这里插入图片描述

优点:是可以找到最强的人!
缺点:第二强的人却不知道是不是名副其实。
可能此时天津饭也可以和比克一战!

最大堆的特点:

1.每个节点最多可以有两个接点
2. 根节点的键值是所有节点里面的最大值,且每个节点的值都比其孩子节点的大
3. 除了根节点没有兄弟节点 最后一个左子节点可以没有兄弟节点 其他节点必须有兄弟节点
看图识最大堆
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ab不是最大堆 c是最大堆

堆其实是用数组表示的树!
i的左子节点:2i+1
i的右子节点:2i+2
i的父节点:(i-1)/2
在这里插入图片描述


在数组中快速创建堆
原:
在这里插入图片描述
目标:

在这里插入图片描述

1.首先找到一个节点的父节点
在这里插入图片描述
如图 我们找到的是87 与其子节点比较 比子节点小 所以要和子节点调整位置 若比子节点大则不需要调整

在这里插入图片描述
2。移动到前一个节点93 做与上一步相同的操作
在这里插入图片描述
结果无需变化
3. 继续移动到前一个父节点 82 与子节点的较大者进行比较 比95要小 所以要调整位置. 在这里插入图片描述
4. 交换后 82又比其子节点小 又需要调整位置
在这里插入图片描述
5.构建堆完成

#include<iostream>
using namespace std;


//堆 数据结构的定义
#define DEFAULT_CAPCITY 128

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

//建最大堆
//堆的初始化
void buildHeap(Heap& heap);
bool initHeap(Heap& heap, int* orginal, int size) {
	//若默认容量大于传入的容量 则把容量设置为默认 否则设置为传入的size
	int capacity = DEFAULT_CAPCITY > size ? DEFAULT_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;
		buildHeap(heap);
	}
	else {
		heap.size = 0;
	}
	return true;
}
/**************
* 将当前节点和和其子节点调整为最大堆
**************/
void adjustDown(Heap& heap, int index) {
	int cur = heap.arr[index]; //当前待调整的系欸但
	int parent, child;
	/*判断是否存在大于当前节点的子节点,如果不存在,则堆本身是平衡的
	*如果存在 则将最大子系欸但与之交换 ,交换后 如果这个子节点还存在
	* 子节点 则需要按照相同的步骤 对这个子节点 进行调整 
	* 
	*/

	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 (cur >= heap.arr[child]) {//不大于 不需要调整
			break;
		}
		else {//大于 需要进行交换位置 然后从子系欸但位置 继续向下调整
			heap.arr[parent] = heap.arr[child];
			heap.arr[child] = cur;
		}
	}
}
/*从最后一个父节点 (size/2的位置)组个往前调整所以父节点(直到根节点),
*确保每一个夫节点都是一个最大堆,最后整体上形成一个最大堆
*/
void buildHeap(Heap& heap) {
	int i;
	
	for (i = heap.size / 2 - 1; i >= 0; i--) {
	
		adjustDown(heap, i);
	}
}
/*
*将当前节点 和父节点调整为最大堆
*/
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;
		}
	}
}
/*最大堆尾部插入节点 同时保证最大堆的特征*/
bool insert(Heap& heap, int value) {
	if (heap.size == heap.capacity)
	{
		fprintf(stderr, "栈空间耗尽!\n");
		return false;
	}
	int index = heap.size;
	heap.arr[heap.size++] = value;
	adjustUp(heap, index);
	return true;
}
//最大元素出堆 把最后一个元素赋值给第一个最大的 再重新进行排列 向下调整
int popHeap(Heap& heap) {
	int index = heap.arr[0];
	heap.arr[0] = heap.arr[--heap.size ];
	adjustDown(heap, 0);
	return index;
}
int main(void) {
	Heap hp; 
	int origVals[] = { 1, 2, 3, 87, 93, 82, 92, 86, 95 }; 
	int i = 0;
	if (!initHeap(hp, origVals, sizeof(origVals) / sizeof(origVals[0]))) { 
		fprintf(stderr, "初始化堆失败!\n");
		exit(-1);
	}
	for (i = 0; i < hp.size; i++) {
		printf("the %dth element:%d\n", i, hp.arr[i]);
	}
	insert(hp, 99);
	printf("在堆中插入新的元素 99,插入结果:\n");
	for (i = 0; i < hp.size; i++) {
		printf("the %dth element:%d\n", i, hp.arr[i]); 
	}
	int a=popHeap(hp);
	printf("堆中的最大元素%d\n", a);
	for (i = 0; i < hp.size; i++) {
		printf("the %dth element:%d\n", i, hp.arr[i]);
	}
	system("pause");
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
数据结构学习资料分享 内容概览: 本次分享包涵了大学计算机相关专业必学的“数据结构”课程的一系列学习资料。主要包括: 算法代码:我们提供了多种数据结构实现代码,包括数组、链表、栈、队列、树、图等。这些代码不仅能帮助你理解数据结构的基本概念,而且能让你明白如何在实际情况中应用这些数据结构。 笔记:详细且系统的笔记,涵盖了数据结构的各个方面,从基础概念到复杂的数据结构、B树等。这些笔记有助于你系统地复习和学习数据结构。 相关书籍推荐:为了更深入地理解数据结构,我们推荐了几本经典的教材和参考书籍。这些书籍将帮助你建立完整的数据结构知识体系。 适用人群: 这份学习资料适用于所有大学计算机相关专业的学生,无论你是初学者还是已经有一定的数据结构基础。同时,对于对数据结构感兴趣的非专业人士,这份资料也是一个很好的起点。 使用建议: 结合理论和实践:在学习的过程中,请结合算法代码和理论知识。尝试自己编写代码实现数据结构,并在遇到问题时参考提供的代码。 由浅入深:建议先从基础的数据结构开始学习,如数组和链表,然后再学习更复杂的数据结构如树和图。 多做练习:数据结构是实践性很强的学科。通过多做练习,你可以更好地理解数据结构的基本概念和原理,并提高编程能力。
### 回答1: 《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本介绍MFC(Microsoft Foundation Classes)的原理、机制以及开发实例的权威性书籍。MFC是微软公司用于开发Windows应用程序的一套类库,是在C++基础上实现的,为开发者提供了一些常用的类和函数,简化了Windows应用程序的开发过程。 这本书首先对MFC的基本原理进行了详细的介绍。它解释了MFC的框架结构,包括应用程序对象、窗口类和消息映射等重要组成部分。同时,它还深入讲解了MFC的事件处理机制、资源管理和界面设计等方面的内容,帮助读者全面理解MFC的内部机制。 除了原理的介绍,这本书还给出了一些实际的开发实例。通过这些实例,读者可以学习如何使用MFC来创建一个完整的Windows应用程序。这些实例包括了常见的功能,例如窗口创建、菜单设计、对话框布局以及文件操作等。通过实际的案例,读者可以加深对MFC的理解,并且在实践中提高自己的开发能力。 总体来说,《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本权威且实用的书籍,适合有一定C++基础并且对Windows应用程序开发感兴趣的读者。通过学习这本书,读者可以更好地掌握MFC的原理和使用技巧,提高自己的软件开发能力。 ### 回答2: 《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本介绍MFC(Microsoft Foundation Classes)的书籍。MFC 是微软公司推出的一个非常重要的C++框架,用于在Windows操作系统上开发图形用户界面应用程序。 这本书首先解释了MFC的基本原理和机制。MFC建立在Windows API之上,它提供了一套面向对象的类库,用于简化Windows GUI应用程序的开发。MFC封装了很多常用的控件和功能,并且提供了很多易于使用的类和函数来处理用户输入、显示输出、消息处理、资源管理等。 书中还介绍了如何使用MFC开发实例。通过这些实例,读者可以学习如何创建一个基本的MFC应用程序,并了解如何利用界面设计器来设计用户界面。书中还提供了一些示例代码,展示了如何处理按钮点击事件、菜单点击事件、对话框等。通过这些实例,读者可以学习到MFC的具体用法和开发技巧。 此外,书中还深入探讨了MFC的高级特性和扩展机制。例如,它介绍了如何使用ActiveX 控件、数据库编程、多线程编程等。这些内容可以帮助读者更加深入地了解MFC并提高开发能力。 总的来说,《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本详细介绍MFC的权威书籍。它适合有一定C++基础,想要学习MFC开发的读者。通过阅读这本书,读者可以系统地学习MFC的原理、机制和开发实例,从而提高Windows GUI应用程序的开发能力。 ### 回答3: 《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本面向Visual C++开发者的权威指南,全面介绍MFC(Microsoft Foundation Class)的原理、机制和开发实例。MFC是微软提供的一组C++类库,用于开发Windows应用程序。 该书首先介绍了MFC的发展历史以及其与Windows操作系统的关系。接着详细解析了MFC的体系结构和设计原理,包括C++面向对象编程、事件和消息处理、窗口和控件等基本概念。通过深入理解MFC的原理和机制,读者可以更加高效地利用MFC进行应用程序开发。 本书还提供了大量的开发实例,涵盖了MFC的各个方面,包括界面设计、数据处理、线程管理等。每个实例都提供了详细的代码和演示步骤,读者可以根据实例来学习并实践MFC的开发技术。通过实例的学习,读者可以了解MFC在实际开发中的应用场景和解决问题的方法。 此外,该书还介绍了一些高级的MFC主题,如自定义控件、打印和预览、国际化等。这些主题涉及到一些常见但较为复杂的开发问题,通过学习这些内容可以进一步提升开发者的技术水平。 总之,《Visual C++权威剖析--MFC的原理、机制与开发实例》是一本全面系统的MFC教程,适合有一定C++编程基础的开发者阅读。通过学习这本书,读者可以深入了解并熟练掌握MFC的原理、机制和开发技术,提高自己在Windows应用程序开发中的能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值