【数据结构】堆的创建

简介: 文章目录一、基于大堆的上下调整1.向上调整(1)解决措施:(2)代码实现(3)测试2.向下调整(1)解决措施:(2)代码实现

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤

📃个人主页 :阿然成长日记 👈点击可跳转

📆 个人专栏: 🔹数据结构与算法🔹C语言进阶

🚩 不能则学,不知则问,耻于问人,决无长进

🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

前言:

在上一篇博客中,主要讲到了关于堆的各种操作。那么本篇博客将会讲讲我们通过堆可以实现的一些作用-----如堆排序

一、基于大堆的上下调整

上一篇博客中的上下调整,都是以调成小堆为目标。那怎样才能实现调成大堆呢?🌸

1.向上调整

1)解决措施:

只需要修改比较符>;改为a[parent]<a[child],即可

(2)代码实现

//向上调整
void AdjustUp(HPDataType* a, int child)
{
  //传入数组,child为孩子节点下标
  int parent = (child - 1) / 2;
  //当一直交换到根,停止
  while (child>0)
  {
    if (a[parent] < a[child])
    {
      Swap(&a[parent], &a[child]);
      child = parent;
      parent = (child - 1) / 2;
    }
    else
      return;
  }
}

(3)测试

输入数组:int a[] = { 2,4,5,3,1,9 };

2.向下调整

(1)解决措施:

只需要修改比较符 <改为child + 1 < n && a[child + 1] >和 a[child],a[child] > a[parent]

因为建大堆,需要找大的那个进行交换。

(2)代码实现

//向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{
  int child = parent * 2 + 1;
  //一直交换到数的最后,也就是数组的最后一个位置
  while (child < n)
  {
    if (child + 1 < n && a[child + 1] >a[child])
    {
      child++;
    }
    if (a[child] > a[parent])
    {
      Swap(&a[child], &a[parent]);
      // 继续往下调整
      parent = child;
      child = parent * 2 + 1;
    }
    else
    {
      return;
    }
  }
}

3.总结

- 大堆 小堆
向上调整 parent>child parent<child
向下调整 比较两个孩子,选择的进行比较交换 选择的进行比较交换

二、创建堆(小堆)

两种方法建堆均以建立小堆为目标。无论是创建小堆还是创建大堆,思路都一样,通过修改Adjust方法即可

建堆【方法一】使用向上调整

创建堆的思路可以通过向上调整,也可通过向下调整。这里讲通过向上调整建立堆.<从上到下>

1.思路

传入参数

a:数组,n:是数组元素个数

1.为p->a开辟n个空间;3.在使用基于小堆的AdjustUp调整,从根逐步向下延伸,其实也就类似于插入调整;

2.代码实现

//建立大堆
void HeapInitArray(HP* p, int* a, int n)
{
  //a:数组,n:是数组元素个数
  assert(p);
  assert(a);
  p->a = (HPDataType*)malloc(sizeof(HPDataType) * n);
  if (p->a == NULL)
  {
    perror("malloc fail");
    exit(-1);
  }
  p->size = n;
  p->capacity = n;
  //把传入数组a复制到p->a中
  memcpy(p->a, a, sizeof(HPDataType) * n);
  // 向上调整,调整成一个小堆
  for (int i = 1; i < n; i++)
  {
    AdjustUp(p->a, i);
  }
}

时间复杂度

O(NlogN)

建小堆【方法二】使用向下调整

这里通过向下调整建立堆.<从下到上>

1.思路:

1.从倒数第一个非叶子节点开始向下调整,因为叶子节点没有左右子树。

2.根据基于小堆的Adjust方法,比较交换。

3.层层向上,下层可以保证是堆。从而可保证向下调整的进行。

所以,我们说这种调整方式是从下到上的。

步骤图

时间复杂度

O(N)

可见向下调整建堆优于向上调整建堆。

相关文章
|
18天前
|
存储 算法 Java
散列表的数据结构以及对象在JVM堆中的存储过程
本文介绍了散列表的基本概念及其在JVM中的应用,详细讲解了散列表的结构、对象存储过程、Hashtable的扩容机制及与HashMap的区别。通过实例和图解,帮助读者理解散列表的工作原理和优化策略。
29 1
散列表的数据结构以及对象在JVM堆中的存储过程
|
20天前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
60 16
|
1月前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
71 1
|
2月前
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
55 5
【数据结构】优先级队列(堆)从实现到应用详解
|
1月前
|
存储 算法 调度
数据结构--二叉树的顺序实现(堆实现)
数据结构--二叉树的顺序实现(堆实现)
|
1月前
|
存储 算法 分布式数据库
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
【初阶数据结构】理解堆的特性与应用:深入探索完全二叉树的独特魅力
|
1月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
1月前
|
存储 算法 Java
【用Java学习数据结构系列】用堆实现优先级队列
【用Java学习数据结构系列】用堆实现优先级队列
31 0
|
1月前
|
存储 算法
【数据结构】二叉树——顺序结构——堆及其实现
【数据结构】二叉树——顺序结构——堆及其实现
|
1月前
【数据结构】大根堆和小根堆
【数据结构】大根堆和小根堆
31 0