最全【开卷数据结构 】还不会实现堆吗?图文并茂深入理解堆,2024年最新原理+实战讲解

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

🍁最大堆的删除

🔺算法分析

💬 代码演示

🌺堆排序

🔺算法分析

💬 代码演示


🌺最大堆与最小堆

🍁最大堆与最小堆的定义


Q:什么是最大堆

**A:**最大堆是指在树中,如果一个结点有儿子结点,其关键字值都不小于其儿子节点的关键字值。最大堆是一棵完全而二叉树,也是一颗最大树。

Q:什么是最小堆

**A:**最小堆是指在树中,如果一个结点有儿子结点,其关键字值都不大于其儿子节点的关键字值。最小堆是一棵完全而二叉树,也是一颗最小树。

**注意:**最小树的根结点的关键字是树中元素最小的,而最大树的根结点是树中关键字值最大的。


可以发现,最大堆和最小堆十分相似,下文中我们就只研究最大堆。

当我们把最大堆看成抽象数据型时,它非常的简单,仅有以下3个操作:

  1. 创建空堆
  2. 把新元素插入堆中
  3. 从队中删除最大元素

🌺最大堆的操作

🍁最大堆的创建


由于堆是一个完全二叉树,可以使用数组存储来表示。我们可以这样来创建最大堆

💬 代码演示
#define MAX_ELEMENTS 200                        //最大堆大小+1
#define HEAP_FULL(n) (n==MAX_ELEMENTS-1)
#define HEAP_EMPTY(n) (!n)
typedef struct{
	int key;
}element;
element heap[MAX_ELEMENTS];
int n=0;

🍁最大堆的插入


🔺算法分析

最大堆的插入操作可以简单看成是“结点上浮”。当我们在向最大堆中插入一个结点时,我们必须满足完全二叉树的标准,那么被插入结点的位置的是固定的。而且要满足父结点关键字值不小于子结点关键字值,那么我们就需要去移动父结点和子结点的相互位置关系。

可以参考下面的图示进行理解

💬 代码演示

**1)**首先检查堆是否满,如果不满,设 i 等于新堆的大小(n+1)。

**2)**使用 while 循环从最大堆的新叶子结点开始,沿着根结点的路径走。

**3)**一直到根结点或者位置 i ,使其父结点 i/2 的值不小于要插入的值。

void insert_max_heap(element item ,int *n){
	//将数插入当前大小为 n 的最大堆中
    if(HEAP_FULL(*n)){
      return;
    }
    int i = ++(*n);
    while((i != 1) && (item.key>heap[i/2].key)){
      heap[i] = heap[i/2];
      i/=2;
    }
    heap[i]=item;
}

🍁最大堆的删除

🔺算法分析

最大堆的删除操作,总是从堆的根结点删除元素。同样根元素被删除之后为了能够保证该树还是一个完全二叉树,我们需要来移动完全二叉树的最后一个结点,让其继续符合完全二叉树的定义,从这里可以看作是最大堆最后一个结点的下沉。

可以参考下面的图示进行理解

现在看来该二叉树虽然是一个完全二叉树,但是它并不符合最大堆的相关定义。我们要在删除完成之后,该完全二叉树依然是最大堆。因此就需要我们来做一些相关的操作。

💬 代码演示
  • **1)**首先删除最大堆的根结点
  • **2)**根结点被删除之后,为了能够保证该树还是一个完全二叉树,我们应该移动完全二叉树的最后一个结点,让其继续符合完全二叉树的定义。这里可以看作是最大堆最后一个结点的下沉
  • **3)**该二叉树虽然是一个完全二叉树,但是它并不符合最大堆的相关定义,我们在左右结点中选择大的一方和下沉的结点比较,令大的一方上浮。
  • **4)**重复步骤 3 ,直到到达叶子结点。
element delete_max_heap(int *n){
	int parent, child;
	element temp, item;
	temp = heap[--*n];
	item = heap[1];
	parent = 1,child=2;
	for(;child <= *n; child = child * 2)
	{
		if( (child < *n) && heap[child].key < heap[child+1].key)
		{// 这一步是为了看当前结点是左子结点大还是右子结点大,然后选择较大的那个子结点
        	child++;
    	}
    	if(temp.key >= heap[child].key)
		{
    		break;
        }
    	heap[parent] = heap[child];//这就是上图中第二步和第三步中黄色部分操作
    	arent = child;// 这其实就是一个递归操作,让parent指向当前子树的根结点
   }
	heap[parent] = temp;
	return item;
}

🌺堆排序

🔺算法分析

通过上文介绍的最大堆的插入算法和删除算法可以直接得到一个时间复杂度为 O(nlogn) 的排序算法。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

…(img-AKo3Aijp-1715096618378)]
[外链图片转存中…(img-iNNNoAVH-1715096618378)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以戳这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值