一. 堆的概念和性质
我们在上一篇博客介绍存储二叉树的两种方式
分别是顺序结构和链式结构
1. 堆的概念
这里注意!!! 这里说的堆和操作系统里面的堆没有半点关系!!!
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
上面这个就是官方的解释了
但是要是我们用通俗的话来说
就是这样子的
大堆 就是所有的父节点都大于等于子节点的堆
小堆 就是所有的子节点都小于等于父节点的堆
如图
2. 堆的性质
堆总是一棵完全的二叉树
堆中某个节点的值总是不大于或者不小于其父节点的值
3. 小题目练练手
1.下列关键字序列为堆的是:()
A 100,60,70,50,32,65
B 60,70,65,50,32,100
C 65,100,70,32,50,60
D 70,65,100,32,50,60
E 32,50,100,70,65,60
F 50,100,70,65,60,32
我们首先来看A
很明显 满足大堆的定义
所以该题选A
我们再来看看B是不是错的
很明显是错的
所以更加确定了答案是A
二. 代码实现以及堆的部分接口函数
1. 结构体代码
结构体代码表示如下
typedef int HeapType; typedef struct Heap { HeapType* arr; int size; int capacity; }HP;
2. 初始化以及销毁
这两段代码很简单 这里就连起来写了
void HeapInit(HP* hp) { assert(hp); hp->arr = NULL; hp->capacity = 0; hp->size = 0; } void HeapDestroy(HP* hp) { assert(hp); free(hp->arr); hp->capacity = 0; hp->size = 0; }
两段代码表示如上
3. 增加数据 (大堆为例)
void HeapPush(HP* hp, HeapType x); • 1
我们这里增加数据要先考虑一点
储存数据的空间够不够
如果不够的话我们就要扩容空间了
这一段代码已经讲过很多次了
我就不讲解了
判断代码如下
assert(hp); if (hp->size==hp->capacity) { int newcapacity = hp->capacity * 2 + 4; HeapType* tmp = realloc(hp->arr, sizeof(HeapType) * newcapacity); if (tmp==NULL) { printf("HeapPush error"); exit(-1); } else { hp->capacity = newcapacity; hp->arr = tmp; } }
当我们这里插入一个75的时候 这里明显是错误的啊 怎么办呢?
这个时候我们就需要将它跟它的父亲比较 是否大于它的父亲
如果不大于就填入
如果小于就交换它和它的父亲
知道孩子等于0为止
下面开始写代码
我们用一个函数来写 防止要复用
void JudgeHeap(HP* hp,int size,int set) { assert(hp); int child = set; int father = (child - 1) / 2; while (child!=0) { if (hp->arr[child]>hp->arr[father]) { HeapType* tmp = 0; tmp = hp->arr[child]; hp->arr[child] = hp->arr[father]; hp->arr[father] = tmp; child = father; father = (child - 1) / 2; } else { break; } } } void HeapPush(HP* hp, HeapType x) { assert(hp); if (hp->size==hp->capacity) { int newcapacity = hp->capacity * 2 + 4; HeapType* tmp = realloc(hp->arr, sizeof(HeapType) * newcapacity); if (tmp==NULL) { printf("HeapPush error"); exit(-1); } else { hp->capacity = newcapacity; hp->arr = tmp; } } hp->arr[hp->size] = x; hp->size++; JudgeHeap(hp,hp->size,hp->size-1); }
整体代码表示如上