二叉树-堆

本文介绍了堆的概念,包括小堆和大堆的定义,以及堆的性质。详细阐述了堆的实现过程,包括向下调整、创建堆、插入元素、删除元素等操作。同时提到了堆在堆排序中的应用。
摘要由CSDN通过智能技术生成

一、堆的概念及结构

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。
  • 堆顶元素一定是最大的或最小的在这里插入图片描述
    在这里插入图片描述

二、堆的实现

1、堆向下调整算法
现在我们给出一个数组,逻辑上看做一颗完全二叉树。我们通过从根节点开始的向下调整算法可以把它调整成一个小堆。向下调整算法有一个前提:左右子树必须是一个堆,才能调整。

int a[] = {27,15,19,18,28,34,65,49,25,37};

//思路
 //1、找parent较小的孩子
 int child=parent*2+1;//parent的左孩子
 while(child<size){
   
 //保证右孩子存在:child+1<size
 if(child+1<size&&array[child+1]<array[child]) 	
 	child+=1;
 //检测parent是否满足堆得性质
 if(array[child]<array[parent])
 	Swap(&array[parent],&array[child]);
//双亲比孩子大,交换完成后,较大的双亲往下移动,可能会导致字数不满足堆的性质
 	parent=child;
 	child=parent*2+1else
 	return}

在这里插入图片描述
2、堆的创建
下面我们给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,现在我们通过算法,把它构建成一个堆。根节点左右子树不是堆,我们怎么调整呢?这里我们从倒数的第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆。

int a[] = {1,5,3,8,7,6};

在这里插入图片描述

3、堆的插入
先插入一个80到数组的尾上,再进行向上调整算法,直到满足堆。
在这里插入图片描述
4、 堆的删除
删除堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。
在这里插入图片描述
5 、堆排序
在这里插入图片描述

三、堆得代码实现

typedef int HDataType;

int Less(HDataType left, HDataType right);
int Greater(HDataType left, HDataType right);

//函数指针变量:可以指向任何有两个HDataType参数以及一个int类型返回值得所有函数
//cmp势函数指针变量,Cmp可以指向Less,也可以指向Greater
//Cmp的类型:int(*)(HDataType,HDataType)

static int (*Cmp)(HDataType left, HDataType right);
typedef int(*CMP)(HDataType, HDataType);

typedef struct Heap
{
   
	HDataType* array;
	int capacity;
	int size;
	CMP Cmp;//函数指针变量
}Heap;

int Less(HDataType left, HDataType righ
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值