一、堆是什么?
堆结构是一种具有特殊性质的基于完全二叉树的树形数据结构
堆是一个完全二叉树,即
- 除了最后一层,其他层的节点都是满的
- 最后一层的节点都是从左到右排列的。
二、堆的特点
堆具有以下特点:有序
2.1 有序
堆是一种有序的数据结构,可以在O(log n)的时间内进行插入、删除和查找操作。
2.2 性能好
堆结构通过维护节点之间的值的大小关系,可以在插入、删除等操作中保持堆的性质,具有较好的性能。
三、堆的插入和删除操作
3.1 堆的插入操作
堆的插入操作相对简单,
堆的插入操作只需要
(1)将新节点插入到最后一层的最后一个位置
(2)进行上浮操作(Heapify Up),以保持堆的性质。
3.2 堆的删除操作
堆的删除操作稍微复杂一些,
堆的插入操作需要分两种情况进行处理:
3.2.1 删除的节点是叶子节点
直接删除该节点即可。
3.2.2 删除的节点不是叶子节点
找到要删除节点的后继节点(即在其右子树中的最小值)或前驱节点(即在其左子树中的最大值),用该节点替换要删除的节点,然后对替换后的节点进行下沉操作(Heapify Down)以保持堆的性质。
四、常见的堆结构
小顶堆、大顶堆和二叉堆是常见的堆结构。
4.1 大顶堆
4.1.1 大顶堆介绍
大顶堆(Max Heap)是一种特殊的堆结构
大顶堆堆的每个节点的值都大于或等于其子节点的值
大顶堆通常用于实现优先队列,其中堆顶元素是最优先的元素。
大顶堆是一种大于等于父节点的二叉堆,即每个节点的值都不小于其父节点的值。
大顶堆的性质为堆顶元素不小于其子节点,即堆顶的值不小于其子节点的值。
4.1.2 大顶堆的插入、删除和查找操作
大顶堆的插入、删除和查找操作可以使用以下函数实现:
- 插入操作:插入节点时,首先检查堆底是否为空,如果是,则直接将新节点插入堆底;如果堆底不为空,则将新节点插入堆底的左子树或右子树中,并进行颜色调整和旋转,以保证大顶堆的性质。
- 删除操作:删除节点时,首先检查堆顶是否为要删除的节点,如果是,则将堆顶的子节点中的最大节点接替堆顶,并进行颜色调整和旋转,以保证大顶堆的性质。
- 查找操作:查找节点时,首先检查堆顶是否为要查找的节点,如果是,则返回堆顶节点;如果堆顶不是要查找的节点,则在左子树或右子树中继续查找,直到找到要查找的节点或者子树为空为止。
4.2 小顶堆
4.2.1 小顶堆介绍
小顶堆(Min Heap)也是一种特殊的堆结构
小顶堆的每个节点的值都小于或等于其子节点的值
小顶堆通常用于实现优先队列,其中堆顶元素是最不优先的元素。
小顶堆是一种小于等于父节点的二叉堆,即每个节点的值都不大于其父节点的值。小顶堆的性质为堆顶元素不大于其子节点,即堆顶的值不大于其子节点的值。
4.2.2 小顶堆的插入、删除和查找操作
小顶堆的插入、删除和查找操作可以使用以下函数实现:
- 插入操作:插入节点时,首先检查堆底是否为空,如果是,则直接将新节点插入堆底;如果堆底不为空,则将新节点插入堆底的左子树或右子树中,并进行颜色调整和旋转,以保证小顶堆的性质。
- 删除操作:删除节点时,首先检查堆顶是否为要删除的节点,如果是,则将堆顶的子节点中的最小节点接替堆顶,并进行颜色调整和旋转,以保证小顶堆的性质。
- 查找操作:查找节点时,首先检查堆顶是否为要查找的节点,如果是,则返回堆顶节点;如果堆顶不是要查找的节点,则在左子树或右子树中继续查找,直到找到要查找的节点或者子树为空为止。
4.3 二叉堆
4.3.1 二叉堆介绍
二叉堆是一种二叉树,其中每个节点都具有两个子节点,分为左子节点和右子节点。
二叉堆的性质为父节点的值不小于其子节点的值,即父节点的值不大于其子节点的值。
在二叉堆中,最大(或最小)的节点称为堆顶(或堆底)
在二叉堆中,堆顶和堆底分别指向堆的最大(或最小)元素。
二叉堆的插入、删除和查找操作可以使用以下函数实现:
4.3.2 二叉堆的插入、删除和查找操作
- 插入操作:插入节点时,首先检查堆底是否为空,如果是,则直接将新节点插入堆底;如果堆底不为空,则将新节点插入堆底的左子树或右子树中,并进行颜色调整和旋转,以保证二叉堆的性质。
- 删除操作:删除节点时,首先检查堆顶是否为要删除的节点,如果是,则将堆顶的子节点中的最大(或最小)节点接替堆顶,并进行颜色调整和旋转,以保证二叉堆的性质。
- 查找操作:查找节点时,首先检查堆顶是否为要查找的节点,如果是,则返回堆顶节点;如果堆顶不是要查找的节点,则在左子树或右子树中继续查找,直到找到要查找的节点或者子树为空为止。