数据结构:堆与堆排序

目录

堆的定义:

堆的实现:

堆的元素插入:

堆元素删除:

堆初始化与销毁:

堆排序:


堆的定义:

堆是一种完全二叉树,完全二叉树定义如下:

一棵深度为k的有n个结点的二叉树,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与满二叉树中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。

    堆分为两类:小堆和大堆。小堆是指堆中任意一个节点都值小于它的孩子节点值。同理,大推指任意一个节点的值都大于它孩子节点的值。

堆的结构:

事实上,堆在逻辑结构上可以看作是一种完全二叉树,但在内存中是以数组的方式存储的。堆内节点的下标可以在计算机内如此计算出来:

左孩子节点的下标 = 父节点的下标*2+1

右孩子节点的下标 = 父节点的下标*2+2

父节点的下标 = (子节点下标 - 1)/2

我们可以很容易看出来,堆数据的插入在逻辑上是一层一层地插入,这一层存满后再到下一层存储。

堆的实现:
Typedef 数据类型 DataType
struct heap {  
       DataType* t;//堆数组内数据类型,指向第一个元素的指针
       int size;  //堆内元素个数
       int capacity;  //堆内元素容量
   }hp;
堆的元素插入:

  由于堆的结构特性,即小堆的双亲节点比它的子节点都要大,大堆的父节点比他的子节点都要小。因此每在数组后插入一个数据都要将这个数据调整到它应该存储的位置,这种调整在逻辑结构中是从下至上的顺序,因此也称为向上调整。

    每次都与自己的双亲节点对比,在小堆中,如果双亲节点的数据大于插入的新数据,那么两节点作数据交换,依次作交换直到双亲节点数据小于该新插入的数据为止。

    首先我们实现一个向上调整的代码:

void AdjustUp(HpType* a, int child)
 {
    int parent = (child  - 1)/2;//先计算出当前插入数据节点的父节点下标
    while(child > 0)
     { 
       if(a[child] < a[parent])
        {
          HpType tmp = a[child];
          a[child] = a[parent];
          a[parent] = tmp;     //交换两节点数据
          parent = child;
          child  = (parent - 1)/2;  //更新父子节点的值,使其指向下一组父子节点
         }
         else
        {
          break;
        } 
      }
  }

实现完调整堆的代码后,我们可以实现插入数据:

void HeapPush(hp* php,HpDataType x)
{
  assert(hp);
  int newCapacity = php->Capacity == 0?4:2*Capacity;
  HpDataType* tmp = (HpDataType*)realloc(php->a, newCapacity*sizeof(HpDataType);
if(tmp == null) //扩容失败的情况
  {
    perror("realloc failed");
   }
   php->t[php->size] = x;
   php->size++;
   AdjustUp(php->t,php->size - 1];//插入后调整堆
}
堆元素删除:

    堆元素删除是将堆首元素删除的算法。对于堆元素删除,通过上面的逻辑,像数组一样单纯将该数据从数组中移除并将后面的数据向前移动是不可行的,因为会导致堆结构的破坏,父节点和子节点不会形成一致的大小关系,因此我们要实现一个算法实现数据删除后对整个堆进行调整的。

   堆元素删除的算法思想是,将堆末尾元素与首元素进行交换,并将末尾元素删除,此时要删除的元素已经被移出。然后将变换后堆的首元素进行向下调整,调整到它应在的位置。

void AdjustDown(HpDataType* a, int parent,int size)
{
    
      int child = parent*2 + 1;
     while(child < size)
        {
       if( child+1 < size && a[parent*2 + 1] > a[parent*2 + 2])
       {
           child++;
       }
           if(a[parent] > a[child])
          { swap(&a[parent],&a[child];
                parent = child;
                child  = parent*2 + 1;
          }
          else
            {
            break;
            }
        }

}

实现完向下调整算法后即可实现堆删除顶部元素算法:

void HeapPop(ph* php)
   {
     assert(php);
     assert(!HeapEmpty(php));
     swap(php->t[0],php->[size-1]); //将首尾元素进行交换
     php->size--;
     AdjustDown(ph,php->t[0],php->size); //向下调整元素
    }
堆初始化与销毁:
void HeapInit(hp* php)
{
  assert(php);
  php->t = null;
  php->size = 0;
  php->Capacity = 0;
}


void HeapDestroy(hp* php)
  {  
    assert(php);
    free(php);
   }
 堆排序:

    堆排序是很重要的一种排序,从堆的增删查改操作衍生而来,由于其较低的时间复杂度运用较为广泛。

    堆排序算法运用到堆的向下调整和,首先传入一个未排序的数组,此时对该数组进行建堆操作。如果我们新建一个堆,再把数组内数据传入堆内会浪费较大的空间。有没有方法可以对数组本身进行建堆操作呢?

    我们可以想象,对数组本身进行建堆操作,把数组看作是从第一个数开始一直插入n - 1个数形成。那么我们就可以将后面n - 1个数进行插入然后向上调整建堆。

void HeapSort(int* a,n)
  {
    for(int i = 1;i < n;i++)
    { AdjustUp(a,i);
          }
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/340620.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序的nodejs+vue课堂在线学习系统教学辅助平台PHP设计与实现

小程序主要实现功能&#xff1a;一、用户的登录与实现 二、课程页面。学生们可以观看课程视频【课程视频有章程】&#xff0c;搜索课程&#xff0c;课程签到&#xff0c;评论课程&#xff0c;课后答题&#xff08;课后成绩&#xff09;&#xff0c;课程互动&#xff08;在视频下…

【深度学习】手把手教你使用 Auto DL 远程服务器连接 PyCharm

前言 文章性质&#xff1a;实操记录 &#x1f4bb; 主要内容&#xff1a;主要记录了如何租用 Auto DL 服务器&#xff0c;以及如何在 PyCharm 中连接远程服务器。 相关文档&#xff1a;如何使用 Auto DL 远程服务器连接 PyCharm 运行代码 - 知乎 冷知识1&#xff1a;小伙伴们不…

c++:string相关的oj题(把字符串转换成整数、344.反转字符串、387. 字符串中的第一个唯一字符、917. 仅仅反转字母)

文章目录 1.把字符串转换成整数题目详情代码思路 2. 344.反转字符串题目详情代码1思路1代码2思路 3. 387. 字符串中的第一个唯一字符题目详情代码思路 4. 917. 仅仅反转字母题目详情代码思路 1.把字符串转换成整数 传送门 题目详情 代码 class Solution { public:int StrToI…

提升用户体验的利器——TTS语音合成软件盘点

提升用户体验的利器——TTS语音合成软件盘点 在当今信息爆炸的时代&#xff0c;人们每天都要处理大量的文本信息。因此&#xff0c;将文本信息转化为语音信息&#xff0c;使得信息能够以更自然、更方便的方式传达给人们&#xff0c;就显得尤为重要。这就是TTS&#xff08;Text…

【C++修行之道】竞赛常用库函数(sort,min和max函数,min_element和max_element、nth_element)

目录 一、sort 1.1sort简介 语法 参数 功能 适用容器 1.2sort的用法 1.3自定义比较函数 示例 1265蓝桥题 —— 排序 二、min和max函数 三、min_element和max_element 497蓝桥题 —— 成绩分析 四、nth_element 一、sort 1.1sort简介 sort函数包含在头文件<a…

手机软件的测试主要有哪些方面去测试,性能测试用什么去测试好?

手机App软件与Web软件系统的架构是不一样的&#xff0c;手机是基于CS架构&#xff0c;而Web系统是基于BS架构的&#xff0c;所以测试手机App软件那么要考虑的东西会更多一些。 分析题主的问题包含两块&#xff1a; 1、手机软件(App)测试主要有哪些方面&#xff1f; 2、手机软件…

【C/C++】C/C++编程——为什么学习 C++?

当提到C的时候&#xff0c;很多人会觉得语法复杂、学习曲线陡峭&#xff0c;并且好像与C语言还有点"纠缠不清"。尽管如此&#xff0c;C仍然是当今世界上最受欢迎和最有影响力的编程语言之一。特别是在当今快速发展的人工智能&#xff08;AI&#xff09;领域&#xff…

java数据结构与算法刷题-----LeetCode645. 错误的集合(位运算解法需要重点掌握)

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 法一&#xff1a;桶排序思想法二&#xff1a;位运算 法一&#x…

gdip-yolo项目解读:gdip模块 |mdgip模块 |GDIP regularizer模块的使用分析

gdip-yolo是2022年提出了一个端到端的图像自适应目标检测框架&#xff0c;其论文中的效果展示了良好的图像增强效果。其提出了gdip模块 |mdgip模块 |GDIP regularizer模块等模块&#xff0c;并表明这是效果提升的关键。为此对gdip-yolo的项目进行深入分析。 gdip-yolo的论文可以…

ARM 驱动 1.22

linux内核等待队列wait_queue_head_t 头文件 include <linux/wait.h> 定义并初始化 wait_queue_head_t r_wait; init_waitqueue_head(&cm_dev->r_wait); wait_queue_head_t 表示等待队列头&#xff0c;等待队列wait时&#xff0c;会导致进程或线程被休眠&…

springsecurity集成kaptcha功能

前端代码 本次采用简单的html静态页面作为演示&#xff0c;也可结合vue前后端分离开发&#xff0c;复制就可运行测试 项目目录 登录界面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</…

详谈c++智能指针!!!

文章目录 前言一、智能指针的发展历史1.C 98/03 的尝试——std::auto_ptr2.std::unique_ptr3.std::shared_ptr4.std::weak_ptr5.智能指针的大小6.智能指针使用注意事项 二、智能指针的模拟实现三、C11和boost中智能指针的关系 前言 C/C 语言最为人所诟病的特性之一就是存在内存…

Quartus II使用小技巧

工程结构&#xff1a; 在建立完某项设计的文件后&#xff0c;依次在其里面新建四个文件夹&#xff0c;分别为&#xff1a;rtl、qprj、msim、doc。 rtl文件夹用于存放设计的源文件。 doc文件夹用于存放设计的一些文档性的资料。 qprj文件夹用于存放quaruts 工程以及quartus生…

陪玩系统:最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码

首发价值29800元的最新商业版游戏陪玩语音聊天系统3.0商业升级独立版本源码 &#xff08;价值29800&#xff09;最新陪玩3.0独立版本 &#xff0c;文件截图 结尾将会附上此系统源码以及详细搭建教程包含素材图仅用于学习使用 陪玩系统3.0独立升级版正式发布&#xff0c;此版本…

项目管理中如何有效沟通?项目管理有效沟通指南

无论是少数人的小型企业还是拥有数十名员工的大公司&#xff0c;有效的沟通对于确保每个人都参与并准备好在项目中实现相同的目标至关重要。 然而&#xff0c;由于沟通不畅&#xff0c;似乎在翻译中总是丢失一些东西。事实上&#xff0c;根据布兰迪斯大学的一项研究&#xff0c…

【复现】SpringBlade SQL 注入漏洞_22

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 SpringBlade 是由一个商业级项目升级优化而来的SpringCloud微服务架构&#xff0c;采用Java8 API重构了业务代码&#xff0c;完全…

一文梳理Windows自启动位置

不同版本的Windows开机自启动的位置略有出入&#xff0c;一般来说&#xff0c;Windows自启动的位置有&#xff1a;自启动文件夹、注册表子键、自动批处理文件、系统配置文件等。如果计算机感染了木马&#xff0c;很有可能就潜伏于其中&#xff01;本文将说明这些常见的Windows开…

GitHub README-Template.md - README.md 模板

GitHub README-Template.md - README.md 模板 1. README-Template.md 预览模式2. README-Template.md 编辑模式References A template to make good README.md. https://gist.github.com/PurpleBooth/109311bb0361f32d87a2 1. README-Template.md 预览模式 2. README-Templat…

CHS_02.2.2.2+调度的目标 调度算法的评价指标

CHS_02.2.2.2调度的目标 调度算法的评价指标 知识总览CPU利用率系统吞吐量周转时间等待时间响应时间 知识回顾 在这个小节中 我们会学习一系列用于评价一个调度算法好坏的一些评价指标 知识总览 包括cpu利用率 系统吞吐量 周转时间 等待时间和响应时间 那在学习的过程中 要注意…

20240122在WIN10+GTX1080下使用字幕小工具V1.2的使用总结(whisper)

20240122在WIN10GTX1080下使用字幕小工具V1.2的使用总结 2024/1/22 19:52 结论&#xff1a;这个软件如果是习作&#xff0c;可以打101分&#xff0c;功能都实现了。 如果作为商业软件/共享软件&#xff0c;在易用性等方面&#xff0c;可能就只能有70分了。 【百分制】 可选的改…