数据结构 - 堆(Heap)

1.堆的定义

堆的形式满足完全二叉树的定义:

  • i < ceil(n/2) ,则节点i为分支节点,否则为叶子节点
  • 叶子节点只可能在最大的两层出现,而最大层次上的叶子节点都依次排列在该层最左侧的位置上
  • 如果有度为1的节点,那么只可能有一个,且该节点只有左孩子

根据堆定义的不同,分为大根堆和小根堆:

  • 大根堆每个节点的值都大于其子节点的值
  • 小根堆每个节点的值都小于其子节点的值

除此之外还有一个重要的内容

  • 单节点也符合堆的特质

2.堆的初始化

堆的初始化可以可以分为如下几个步骤(以初始化最大根堆为例):

  1. 首先初始化为完全二叉树形式。

  2. 从最后一个具有孩子节点的节点进行调整,如果以该元素为根的子树是最大根堆,则不进行操作,否则将该子树调整为最大根堆(调整思路为不断与子节点进行比较和交换,直至满足最大根堆要求为止)。

  3. 数组:[2,7,26,25,19,17,90,3],初始化为完全二叉树形式。

  1. 调整最后一个具有孩子节点的节点[4],符合最大根堆要求,不进行操作。

  1. 调整节点[3],以满足最大根堆要求,交换[3][7]

  1. 调整节点[2],以满足最大根堆要求,交换[2][5]

  1. 调整节点[1],以满足最大根堆要求,交换[1][3]后继续交换[3][7],最终完成初始化,满足最大根堆要求。

3.堆节点的插入和调整

如上图所示,在如上所示图中插入44

  1. 堆的初始化和插入的C++语言代码描述
/**
*@Author : Kindear
*@Intro : DataStrcut C++ Code 以最大根堆为例
**/
#include <bits/stdc++.h>
#define ARR_SIZE 20
using namespace std;
typedef int ElementType;
void AdjustUp(ElementType A[],int k, int len) //该方法用于堆插入调整
{
int Tmp = A[k]; //暂存k位置的数值
int i = k/2; //父节点的下标
while(i > 0 && A[i] < Tmp)
{
//如果该节点大于父节点,那么就交换两者的位置,满足最大根堆的要求
A[k] = A[i];
k = i;
i = k/2; //继续向上寻找并调整,直至满足最大根堆要求
}
A[k] = Tmp; //
}
void AdjustDown(ElementType A[],int k,int len) //该方法用于堆的初始化
{
int Tmp = A[k];
for(int i = 2*k; i <= len; i*=2) //向下筛选
{
if(i < len && A[i] < A[i+1]) i++;
if(Tmp > A[i]) break;
else
{
A[k] = A[i];
k = i;
}
}
A[k] = Tmp;
}
void BuildMaxHeap(ElementType A[],int len)
{
for(int i= len/2 ; i > 0; i--)
{
AdjustDown(A,i,len);
}
}
void PrintfElementArray(ElementType A[],int len)
{
for(int i=1;i<=len;i++)
{
printf("%d%c",A[i],i==len?'\n':' ');
}
}
int main()
{
ElementType A[] = {0,2,7,26,25,19,17,90,3};
ElementType B[ARR_SIZE];
BuildMaxHeap(A,8);
PrintfElementArray(A,8);
for(int i=0;i<=8;i++)
{
B[i] = A[i];
}
B[9] = 44;//插入44
AdjustUp(B,9,9);
PrintfElementArray(B,9);
}
参考文档

[1] 数据结构堆可视化:https://visualgo.net/zh/heap

最新文章

  1. linux内核调度算法(2)--CPU时间片如何分配 转!
  2. 【java项目小记--JManager】项目开始原因及github部署
  3. Visual Studio 后期生成事件复制配置文件
  4. Windows Phone 8.1中处理后退键的HardwareButtons.BackPressed事件
  5. Beta版本冲刺Day4
  6. 如何用phpstorm编辑远程项目
  7. python日志输出
  8. 详解ARM的AMBA设备中的 DMA设备PL08X的Linux驱动
  9. xml版本学生管理系统
  10. ThinkPHP 3.1 404页面的设置
  11. 全平台轻量级 Verilog 编译器 & 仿真环境
  12. Scanner扫描器
  13. Unhandled event loop exception Java heap space
  14. java HttpClient设置代理
  15. .net core mvc 区域路由设置(配置)
  16. 北大poj- 1012
  17. Python2中生成时间戳(Epoch,或Timestamp)的常见误区
  18. Dream team: Stacking for combining classifiers梦之队:组合分类器
  19. mysql按位的索引判断值是否为1
  20. FastStone Capture无法录制系统声音解决方法(win10)

热门文章

  1. Python1--简介及基础语法
  2. Springboot中登录后关于cookie和session拦截案例
  3. Cortex-M4的快速memcpy,根据数据对齐情况自动优化,速度为普通memcpy的1.3到5.2倍
  4. C# 解析获取Url参数值
  5. ZooKeeper的十二连问,你顶得了嘛?
  6. PHP使用FilesystemIterator迭代器遍历目录
  7. Pyinstaller打包: 将资源文件或文件夹打包到最后生成的exe中
  8. Cross-Site Scripting: Reflected
  9. git 合并两个分支的某个文件
  10. HDU多校1003-Divide the Stones(构造)