数据结构初阶 堆(一)

简介: 数据结构初阶 堆(一)

一. 堆的概念和性质

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

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

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);
}


整体代码表示如上

目录
相关文章
|
6天前
|
存储 算法
【数据结构】堆
【数据结构】堆
|
1月前
|
算法 安全 大数据
揭秘!Python堆与优先队列:数据结构的秘密武器,让你的代码秒变高效战士!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能,助你提升算法效率。堆用于快速找大数据集的第K大元素,如示例所示,时间复杂度O(n log k)。PriorityQueue在多线程中智能调度任务,如模拟下载管理器,按优先级处理任务。掌握这些工具,让代码运行更高效!
49 1
|
5天前
|
存储 算法 Linux
【数据结构】树、二叉树与堆(长期维护)(1)
【数据结构】树、二叉树与堆(长期维护)(1)
|
11天前
|
搜索推荐 算法 Go
深入探索堆:Go语言中的高效数据结构
深入探索堆:Go语言中的高效数据结构
|
5天前
|
算法
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
【数据结构】树、二叉树与堆(长期维护)(2)
|
11天前
【数据结构】二叉树顺序实现(大堆)-->赋源码
【数据结构】二叉树顺序实现(大堆)-->赋源码
23 4
|
1月前
|
存储 算法
【数据结构】堆,堆的实现,堆排序,TOP-K问题
数据结构——堆,堆的实现,堆排序,TOP-K问题
22 1
【数据结构】堆,堆的实现,堆排序,TOP-K问题
|
4天前
|
存储
全局变量和局部变量在堆和栈的区别
全局变量和局部变量在堆和栈的区别
9 0
|
1月前
|
存储 算法 调度
惊呆了!Python高级数据结构堆与优先队列,竟然能这样优化你的程序性能!
【7月更文挑战第10天】Python的heapq模块实现了堆和优先队列,提供heappush和heappop等函数,支持O(log n)时间复杂度的操作。优先队列常用于任务调度和图算法,优化性能。例如,Dijkstra算法利用最小堆加速路径查找。堆通过列表存储,内存效率高。示例展示了添加、弹出和自定义优先级元素。使用堆优化程序,提升效率。
41 2
|
1月前
|
存储 缓存 算法
堆和栈的区别及应用场景
堆和栈的区别及应用场景