数据结构初阶 堆(一)

一. 堆的概念和性质

我们在上一篇博客介绍存储二叉树的两种方式

分别是顺序结构和链式结构

数据结构初阶 初识二叉树-CSDN博客

1. 堆的概念

这里注意!!! 这里说的堆和操作系统里面的堆没有半点关系!!!

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

上面这个就是官方的解释了

但是要是我们用通俗的话来说

就是这样子的

大堆 就是所有的父节点都大于等于子节点的堆

小堆 就是所有的子节点都小于等于父节点的堆

如图

2. 堆的性质

  1. 堆总是一棵完全的二叉树

  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 HPDateType;

typedef struct Heap
{
	HPDateType* a;
	int size;
	int capacity;
}HP;

2. 初始化以及销毁

这两段代码很简单 这里就连起来写了

复制代码
void HeapInit(HP* php)
{
	assert(php);
	php->a = (HPDateType*)malloc(sizeof(HPDateType) * 4);
	if (php->a == NULL)
	{
		perror("malloc fail");
		return;
	}
	php->size =0;
	php->capacity = 4;
}
void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);
	php = NULL;
	php->size = 0;
	php->capacity = 0;
}

两段代码表示如上

3. 增加数据 (大堆为例)

复制代码
void HeapPush(HP* php, HPDateType x)

我们这里增加数据要先考虑一点

储存数据的空间够不够

如果不够的话我们就要扩容空间了

这一段代码已经讲过很多次了

我就不讲解了

判断代码如下

复制代码
	assert(php);
	if (php->size == php->capacity)
	{
		HPDateType* tmp = (HPDateType*)realloc(php->a,sizeof(HPDateType) * php->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		php->a = tmp;
		php->capacity *= 2;
	}
	php->a[php->size] = x;
	php->size++;

当我们这里插入一个75的时候 这里明显是错误的啊 怎么办呢?

这个时候我们就需要将它跟它的父亲比较 是否大于它的父亲

如果不大于就填入

如果小于就交换它和它的父亲

知道孩子等于0为止

下面开始写代码

我们用一个函数来写 防止要复用

复制代码
void Swap(HPDateType* p1, HPDateType* p2)
{
	HPDateType x = *p1;
	*p1 = *p2;
	*p2 = x;
}
//除child这个位置,前面数据构成堆
//向上调整
void AdJustUp(HPDateType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			//更新父亲的位置
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPush(HP* php, HPDateType x)
{
	assert(php);
	if (php->size == php->capacity)
	{
		HPDateType* tmp = (HPDateType*)realloc(php->a,sizeof(HPDateType) * php->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		php->a = tmp;
		php->capacity *= 2;
	}
	php->a[php->size] = x;
	php->size++;
	AdJustUp(php->a, php->size - 1);
}

整体代码表示如上

相关推荐
立志成为大牛的小牛4 小时前
数据结构——十七、线索二叉树找前驱与后继(王道408)
数据结构·笔记·学习·程序人生·考研·算法
Algo-hx4 小时前
数据结构入门 (七):从“链接”到“分支” —— 初探树与二叉树
数据结构
小贾要学习5 小时前
【数据结构】C++实现红黑树
数据结构·c++
周杰伦_Jay8 小时前
【Java集合体系】全面解析:架构、原理与实战选型
java·开发语言·数据结构·链表·架构
tkevinjd9 小时前
反转链表及其应用(力扣2130)
数据结构·leetcode·链表
HalvmånEver9 小时前
红黑树实现与原理剖析(上篇):核心规则与插入平衡逻辑
数据结构·c++·学习·算法·红黑树
Rubisco..13 小时前
牛客周赛 Round 111
数据结构·c++·算法
代码小菜鸡66614 小时前
java 常用的一些数据结构
java·数据结构·python
火山灿火山14 小时前
详解AVL树旋转操作实现
数据结构·c++
少许极端14 小时前
算法奇妙屋(六)-哈希表
java·数据结构·算法·哈希算法·散列表·排序