数据结构-堆排序问题

堆排序(Heap Sort)是一种利用堆数据结构,实现的比较高效的排序算法,它的时间复杂度为O(nlogn)。堆排序的基本思想可以概括为下面三个步骤:

  1. 构建初始堆:将待排序序列构造成一个堆,称为初始堆。在这里我们采用最大堆,也就是父节点的元素值大于或等于其子节点。

  2. 对堆进行排序:取出当前堆的根节点(最大值),并将其与堆的最后一个节点进行互换。移除最后一个节点,然后对剩余的堆进行调整,使其重新成为一个堆。重复此过程,直到堆中仅剩下根节点。

  3. 得到有序序列:当堆中仅剩下根节点时,整个堆也变成了有序序列。

堆排序的过程可以看作是不断将最大的元素移到序列的末尾,因此称其为选择排序的一种。

堆排序需要实现两个基本操作:

从一个无序序列构建一个堆和在输出堆顶元素后,调整堆。

其中构建堆的时间复杂度为O(n),而调整堆的时间复杂度为O(logn)。

因此,整个堆排序的时间复杂度为O(nlogn)。

堆排序的优点是:空间复杂度较好,只需要一个额外的空间来存储堆节点。同时,由于不需要递归和多余的赋值操作,其时间复杂度相对较稳定。

void HeapSort(int*a,int n)
{  
  //建堆,向上调整
  for(int i = 1; i < n; ++i) 
  {
    AdjustUP(a,i);
  }
  // 交换堆顶元素和最后一个元素,并调整堆
  int end = n - 1;
  while (end > 0) {
    Swap(&a[end], &a[0]);
    AdjustDown(a,end,0);
    --end;
  }
}

int  main() {
  int n;
  printf("请输入学生数:");
  scanf("%d", &n);
  int* arr = (int*)malloc(n * sizeof(int)); // 动态分配数组内存空间
  printf("请输入学生的分数:");
  for (int i = 0; i < n; i++) {
    scanf("%d ", &arr[i]);
  }
  //int a[10] = { 1,2,8,9,4,5,15,16,19,10 };
  //int n = sizeof(a) / sizeof(a[0]);
  HeapSort(arr, n);
  printf("分数结果是");
  for (int i = 0; i < n; ++i) {
    printf("%d ", arr[i]);
  }
  return 0;
}

 

这是一段 C 语言代码,实现了堆排序算法。堆排序是利用堆的数据结构设计的一种排序算法,在时间复杂度为O(nlogn)的同时,也具有很好的空间利用率。这段代码中,首先使用 AdjustUP 函数将原始数组构成一个最大堆(即父节点大于等于左右子节点),然后在每次交换堆顶元素和最后一个元素的位置时,利用 AdjustDown 函数调整堆的结构,使得堆保持最大堆的性质。

     该代码中从标准输入读取 n 和 n 个学生分数,然后对它们进行排序并输出结果。如果需要运行该代码,需要自己实现 AdjustUP 和 AdjustDown 两个函数,或者从其他文件中引用这些函数。

其中AdjustUP 和 AdjustDown 两个函数

// AdjustUP 函数:向上调整堆
void AdjustUP(int* a, int child) {
  int parent = (child - 1) / 2;
  while (child > 0 && a[child] > a[parent]) {
    Swap(&a[child], &a[parent]);
    child = parent;
    parent = (child - 1) / 2;
  }
}

// AdjustDown 函数:向下调整堆
void AdjustDown(int* a, int n, int parent) {
  int child = 2 * parent + 1; // 初始化为左子节点
  while (child < n) {
    // 找到左右子节点中较大的一个
    if (child + 1 < n && a[child + 1] > a[child]) {
      ++child;
    }
    // 如果父节点比子节点都大,则跳出循环
    if (a[parent] >= a[child]) {
      break;
    }
    // 否则交换父节点和子节点,并继续向下调整
    Swap(&a[parent], &a[child]);
    parent = child;
    child = 2 * parent + 1;
  }
}

其中,Swap 函数为交换两个变量的值的函数,应该在代码中进行定义。在 AdjustUP 函数中,首先根据子节点的位置计算出其父节点的位置,然后不断将子节点与其父节点进行比较,如果子节点较大则将它们交换位置,直到子节点比其父节点小或者到达堆的根节点。在 AdjustDown 函数中,首先从指定的父节点开始,计算出其左右子节点中较大的一个(如果有的话),然后比较该子节点与父节点的大小关系,如果父节点比子节点都大,则说明已经满足最大堆的性质,此时可以结束函数;否则将父节点和子节点交换位置,并以新的父节点继续向下调整。

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

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

相关文章

点亮孙武不夜城 拉响惠民经济新引擎

凡战者&#xff0c;以奇制胜。这次的招商很特别—孙武不夜城招商项目正式启动&#xff01;      无租金、无投资、无风险合伙人制。      现诚邀广大商家合作&#xff0c;相聚不夜城。同此道者&#xff0c;合大志&#xff0c;鸣鼓纳征&#xff0c;亮惠民夜生活&#xf…

一位年薪35W的测试被开除,回怼的一番话,令人沉思

一位年薪35W测试工程师被开除回怼道&#xff1a;“反正我有技术&#xff0c;在哪不一样” 一技傍身&#xff0c;万事不愁&#xff0c;当我们掌握了一技之长后&#xff0c;在职场上说话就硬气了许多&#xff0c;不用担心被炒&#xff0c;反过来还可以炒了老板&#xff0c;这一点…

如何防御恶意流量攻击(CC、DDoS)?

随之网络安全的地位不断提高&#xff0c;越来越多的攻击得以解决&#xff0c;但随之而来的也是新的攻击在变着花样地出现&#xff0c;就好比DDoS攻击与CC攻击就是这些年较为常见的攻击手段&#xff0c;这两种攻击分别针对网站的应用层和网络层。 我们网站运维人员一定要做好功课…

Vue--构建亚马逊多账号的后台数据展示

效果展示&#xff1a; 根据自创的账号个数来创建对应的表格个数 移动到对应商品时展示该商品的日出售变化情况 设计思路&#xff1a; 获取亚马逊平台个人账号数据传入自定义组件<WeekTable> <WeekTable>组件获取到数据后&#xff0c;就会重载DOM元素内容。我们在组…

Ae 入门系列之七:文本动画

Ae 提供了多种制作文本动画的方法。既可以在时间轴面板上基于基本属性手动添加关键帧&#xff0c;还可以使用专门的文本动画制作工具&#xff0c;或者直接使用动画预设。有关文本图层的基础知识请参阅&#xff1a;《Ae&#xff1a;文本图层操作基础》提示&#xff1a;文本动画的…

员工培训Employee Training

前言 加油 原文 员工培训常用会话 ❶ When is our training session? 我们的课程培训在什么时候? ❷ You shouldn’t be absent at training sessions. 你不能缺席课程培训。 ❸ You should follow these rules and regulations. 你应该遵守这些规章制度。 ❺ The staff…

ROS实践11 自定义头文件并调用

文章目录运行环境&#xff1a;思路&#xff1a;1.1 编写头文件1.2 includepath添加头文件路径1.3 编写可执行文件1.4 配置文件1.5 编译运行运行环境&#xff1a; ubuntu20.04 noetic 宏基暗影骑士笔记本 思路&#xff1a; 类和函数&#xff1a; 头文件 声明 可执行文件 定义…

测试行业3年经验,从大厂裸辞后,面试阿里、字节全都一面挂,被面试官说我的水平还不如应届生

测试员可以先在大厂镀金&#xff0c;以后去中小厂毫无压力&#xff0c;基本不会被卡&#xff0c;事实果真如此吗&#xff1f;但是在我身上却是给了我很大一巴掌... 所谓大厂镀金只是不卡简历而已&#xff0c;如果面试答得稀烂&#xff0c;人家根本不会要你。况且要不是大厂出来…

Leetcode6365. 最少翻转操作数题解

题目在此&#xff1a;力扣 首先&#xff0c;先祝福自己本周周赛过了三题。耶耶耶耶耶耶&#xff01;虽然第一题因为脑子不好使想了半天&#xff0c;还WA了一次。衷心祈祷今年力扣能上1800分&#xff01;&#xff01;&#xff01; 这道题&#xff0c;我看了一些通过人数&#x…

【面试】Java高频面试题(2023最新整理)

文章目录一、java基础1、JDK 和 JRE 有什么区别&#xff1f;2、 和 equals 的区别是什么&#xff1f;3、final 在 java 中有什么作用&#xff1f;4、java 中的 Math.round(-1.5) 等于多少&#xff1f;5、String 属于基础的数据类型吗&#xff1f;6、String str"i"与 …

JUC并发编程高级篇第三章之CAS[Unsafe和原子增强类]

文章目录1、CAS的简介1.1、什么是CAS1.2、使用CAS的前后对比1.3、CAS如何做到不加锁的情况&#xff0c;保证数据的一致性1.4、什么是Unsafe类1.5、CAS方法参数详解1.6、CAS的原理1.7、 CAS的缺点2、原子操作类2.1、基本类型原子类2.2、数据类型原子类2.3、引用类型原子类2.4、对…

66-插入排序

目录 1.直接插入排序 2.折半插入排序 3.在数组arr[l...r]上使用插入排序 类似打扑克牌&#xff0c;整理牌的时候&#xff0c;都是把乱的牌向已经码好的牌中插入——天然的插入排序。 1.直接插入排序 每次选择无序区间的第一个元素&#xff0c;插入到有序区间的合适位置&am…

chatGPT中国入口-ChatGPT评论文章-ChatGPT怎么用

国内怎么玩chatGPT 如果您在国内使用ChatGPT&#xff0c;主要的问题可能是连接OpenAI服务器的速度和稳定性。由于OpenAI位于美国&#xff0c;可能受到中国的网络限制和防火墙的影响&#xff0c;造成访问速度比较慢或不稳定。为了解决这个问题&#xff0c;您可以采取以下方法&a…

idea常用快捷键,包的介绍,访问修饰符

这里有的是我自己定义的快捷键&#xff0c;可以到图片是指定位置查看对应的快捷键是什么。删除当前行&#xff0c;Ctrld复制当前行&#xff0c;自己配置CtrlShift向下箭头补全代码 alt /注释Ctrl /自动导入包在上面位置把两个选项选中&#xff0c;在要导入包的红色位置输入al…

(C++)模板分离编译面对的问题

什么是分离编译模板的分离编译什么是分离编译 一个程序&#xff08;项目&#xff09;由若干个源文件共同实现&#xff0c;而每个源文件单独编译生成目标文件&#xff0c;最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。 模板的分离编译 假如有以下…

Spring入门(万字详细附代码讲解)

1.Spring介绍 Spring其实就是一种开源框架,指的是Spring Framework,具有良好的生态,这也是Spring经久不衰的原因 用一句话概括,Spring就是一个集成了众多工具和方法的IOC容器 2.IOC容器 什么是IOC容器呢? IOC的中文翻译过来就是控制反转,IOC容器其实就是控制反转容器 那什…

2022蓝桥杯省赛——卡片

问题描述 小蓝有 k 种卡片, 一个班有 n 位同学, 小蓝给每位同学发了两张卡片, 一位同学的两张卡片可能是同一种, 也可能是不同种, 两张卡片没有顺序。没有两位同学的卡片都是一样的。 给定 n, 请问小蓝的卡片至少有多少种? 输入格式 输入一行包含一个正整数表示 n 。 输出…

Vue中的slot插槽

目录 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 (2)插槽的好处和使用场景 &#xff08;3&#xff09;slot插槽的分类 1、默认插槽 2、具名插槽 3、作用域插槽 &#xff08;一&#xff09;什么是slot插槽 (1)slot插槽的作用 slot具有“占坑”的作用…

Hadoop MapReduce各阶段执行过程以及Python代码实现简单的WordCount程序

视频资料&#xff1a;黑马程序员大数据Hadoop入门视频教程&#xff0c;适合零基础自学的大数据Hadoop教程 文章目录Map阶段执行过程Reduce阶段执行过程Python代码实现MapReduce的WordCount实例mapper.pyreducer.py在Hadoop HDFS文件系统中运行Map阶段执行过程 把输入目录下文件…

【GoF 23 概念理解】AOP面向切面编程

1. 什么是AOP——面向切面编程 AOP是一种编程范式&#xff0c;提供了一种从宁一个角度来考虑程序结构以完善面向对象编程&#xff08;OOP&#xff09; AOP是一个思想上的变化——主从换位&#xff0c;让原本主动调用的模块变成了被动等待&#xff0c;甚至在毫不知情的情况下被…
最新文章