【C语言】堆排序
堆排序即利用堆的思想来进行排序,总共分为两个步骤:
1. 建堆
升序:建大堆
降序:建小堆
原因分析:
若升序建小堆时间复杂度是O(N^2)

升序建大堆,时间复杂度O(N*logN)

所以升序建大堆,降序建小堆
2. 利用堆删除思想来进行排序
建堆和堆删除中都用到了向下调整,因此掌握了向下调整,就可以完成堆排序。
代码实现
#include<stdio.h>//交换函数
void Swap(int* px, int* py)
{int tmp = *px;*px = *py;*py = tmp;
}
//向下调整算法
void AdjustDown(int* 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 = child * 2 + 1;}else{break;}}
}
void HeapSort(int* a, int n)
{//建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(a, n, i);}int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}
int main()
{int a[] = { 0,4,3,6,7,8,1 };HeapSort(a, sizeof(a) / sizeof(int));return 0;
}
运行结果

若是建小堆则只需要把向下调整中的>改成<,修改后如下
if (child + 1 < n && a[child + 1] < a[child])
{child++;
}
if (a[child] < a[parent])
{Swap(&a[child], &a[parent]);parent = child;child = child * 2 + 1;
}
运行结果

当然我们也可以先写一个堆的数据结构再进行堆排序,但是这显然不如上面的快速且节省空间
自主实现数据结构堆再进行堆排序
代码实现
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<string.h>typedef int HPDataType;
typedef struct Heap
{HPDataType* a;int size;int capacity;
}HP;
//初始化
void HPArrayInit(HP* hp, HPDataType* a, int n);
//销毁
void HPDestroy(HP* hp);
// 堆的插入
void HPPush(HP* hp, HPDataType x);
// 堆的删除
void HPPop(HP* hp);
// 取堆顶的数据
HPDataType HPTop(HP* hp);
// 堆的数据个数
int HPSize(HP* hp);
// 堆的判空
int HPEmpty(HP* hp);
//向上调整算法
void Adjustup(HPDataType* a, int child);
//向下调整算法
void AdjustDown(HPDataType* a, int n, int parent);void HPArrayInit(HP* hp, HPDataType* a, int n)
{assert(hp);hp->a = (HPDataType*)malloc(sizeof(HPDataType) * n);if (hp->a == NULL){perror("malloc fail");return;}memcpy(hp->a, a, n * sizeof(HPDataType));hp->size = hp->capacity = n;//向上调整,建堆时间复杂度O(N*logN)for (int i = 1; i < hp->size; i++){Adjustup(hp->a, i);}//向下调整,建堆时间复杂度O(N)for (int i = (hp->size - 1 - 1) / 2; i >= 0; i--){AdjustDown(hp->a, hp->size, i);}
}
//销毁
void HPDestroy(HP* hp)
{assert(hp);hp->size = hp->capacity = 0;free(hp->a);hp->a = NULL;
}
//交换函数
void Swap(HPDataType* px, HPDataType* py)
{HPDataType tmp;tmp = *px;*px = *py;*py = tmp;
}
//向上调整算法
void Adjustup(HPDataType* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (parent - 1) / 2;//找原本父亲的父亲下标}else{break;}}
}
// 堆的插入
void HPPush(HP* hp, HPDataType x)
{assert(hp);//扩容if (hp->size == hp->capacity){int newcapacity = hp->capacity == 0 ? 4 : 2 * hp->capacity;HPDataType* tmp = (HPDataType*)realloc(hp->a, sizeof(HPDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return;}hp->a = tmp;hp->capacity = newcapacity;}hp->a[hp->size++] = x;Adjustup(hp->a, hp->size - 1);
}
//向下调整算法
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 = child * 2 + 1;}else{break;}}
}
// 堆的删除
void HPPop(HP* hp)
{assert(hp);assert(hp->size > 0);Swap(&hp->a[0], &hp->a[hp->size - 1]);hp->size--;AdjustDown(hp->a, hp->size, 0);
}
// 取堆顶的数据
HPDataType HPTop(HP* hp)
{assert(hp);return hp->a[0];
}
// 堆的数据个数
int HPSize(HP* hp)
{assert(hp);return hp->size;
}
// 堆的判空
int HPEmpty(HP* hp)
{assert(hp);return hp->size == 0;
}
void HeapSort(int* a, int n)
{HP hp;HPArrayInit(&hp, a, n);int i = 0;while (!HPEmpty(&hp)){a[i++] = HPTop(&hp);//将堆顶数据放入数组中HPPop(&hp);//再已放入数组中的堆顶数据删除}HPDestroy(&hp);
}
int main()
{int a[] = { 60,70,65,50,32,100 };HeapSort(a, sizeof(a) / sizeof(int));for (int i = 0; i < sizeof(a) / sizeof(int); i++){printf("%d ", a[i]);}return 0;
}
运行结果

欢迎各位大佬一起学习交流~
相关文章:
【C语言】堆排序
堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1. 建堆 升序:建大堆 降序:建小堆 原因分析: 若升序建小堆时间复杂度是O(N^2) 升序建大堆,时间复杂度O(N*logN) 所以升序建大堆…...
ntp服务重启报错Failed to restart ntpd.service: Unit is masked.
问题概述: 重启ntp服务报错Failed to restart ntpd.service: Unit is masked,使用systemctl unmask ntpd.service命令关闭屏蔽还是报错Failed to restart ntpd.service: Unit is masked 解决方法: 重装ntp服务 yum remove ntpyum install…...
面试题-每日5到
16.Files的常用方法都有哪些? Files.exists():检测文件路径是否存在 Files.createFile():创建文件 Files.createDirectory():创建文件夹 Files.delete():删除一个文件或目录 Files.copy():复制文件 Files.move():移动文件 Files.size():查看文件个数 Files.read():读…...
代码美学大师:打造Perl中的个性化代码格式化工具
代码美学大师:打造Perl中的个性化代码格式化工具 在软件开发过程中,代码的可读性至关重要。Perl,作为一种灵活的脚本语言,允许开发者以多种方式实现代码格式化。自定义代码格式化工具不仅能提升代码质量,还能加强团队…...
成为一名月薪 2 万的 web 安全工程师需要掌握哪些技能?
现在 web 安全工程师比较火,岗位比较稀缺,现在除了一些大公司对学历要求严格,其余公司看中的大部分是能力。 有个亲戚的儿子已经工作 2 年了……当初也是因为其他的行业要求比较高,所以才选择的 web 安全方向。 资料免费分享给你…...
Linux中如何添加磁盘分区
在Linux中添加分区通常涉及到几个步骤,包括识别磁盘、创建分区、格式化分区,以及挂载或将其用作特定的文件系统类型(如LVM、RAID等)。以下是一个基本的步骤指南,假设你正在使用命令行界面(CLI)和…...
计算机毕业设计Hadoop+Hive专利分析可视化 面向专利的大数据管理系统 专利爬虫 专利数据分析 大数据毕业设计 Spark
《Hadoop专利大数据分析可视化系统》开题报告 一、选题背景与意义 随着信息技术的飞速发展,全球数据量呈现爆炸式增长,特别是在专利领域,数据的积累和更新速度更是惊人。专利数据不仅包含了技术创新的详细信息,还反映了行业的发…...
git是什么?git和svn的区别。git的一些命令
Git是什么 Git是一个开源的分布式版本控制系统(Distributed Version Control System,简称DVCS),它可以有效、高速地处理从很小到非常大的项目版本管理。版本控制系统能追踪项目从开始到结束的整个过程,对编程人员而言…...
RK3568平台(触摸篇)双屏异触调试
一.现象 现象:准备两块主屏都接触摸框,A屏的HDMIOUT外接B屏的HDMIIN,用手触摸A屏,发现A屏没有触摸,A屏幕的触摸现象在B屏那边。 现要求:用手触摸A屏,A屏要有现象,不能现象在B屏那边…...
angular cmd
npm uninstall -g angular/cli npm install -g angular/cli npm install -g angular/cli17 ng update angular/core17 angular/cli17 # 安装 typescript npm i -g typescript5.3.2 # 安装 Angular CLI npm install -g angular/cli17.3.8 # 或者 cnpm install -g angular/cli…...
[ACTF2020 新生赛]BackupFile1
打开题目 利用disearch扫描,发现源文件index.php.bak 下载下来 打开文件 代码审计,翻译一下 翻译代码为: <?php include_once "flag.php"; //这一行使用 include_once 函数来包含(或插入)另一个 PHP …...
Springboot学习-day16
Springboot学习-day16 Springboot是spring家族中的一个全新框架,用来简化spring程序的创建和开发过程。在以往我们通过SpringMVCSpringMybatis框架进行开发的时候,我们需要配置web.xml,spring配置,mybatis配置,然后整…...
Map 31
...
dfs,CF 196B - Infinite Maze
一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 https://codeforces.com/problemset/problem/196/B 二、解题报告 1、思路分析 考虑如何判断一条路径可以无限走? 我们对朴素的网格dfs改进,改进为可以dfs网格外的区域 如果存在某个…...
鸿蒙应用框架开发【JS注入与执行】 Web
JS注入与执行 介绍 本示例基于H5游戏,通过arkui的button实现对游戏实现基本控制,展示webview的JS注入与执行能力,及native应用与H5的通信能力。 效果预览 使用说明 1.设备连接热点,可访问互联网。 2.打开应用,通过…...
AI问答:理解 DRG / Diagnosis Related Group / 按疾病诊断相关分组
DRG(Diagnosis Related Group)系统,中文译作“按疾病诊断相关分组”,是一种根据病情临床相似程度和资源消耗水平将住院病人进行分组的系统。以下是对DRG系统的详细理解: 一、定义与原理 1.1、定义:DRG系统…...
多个线程同时调用接口
1、线程的基本概念 线程是程序执行的最小单元。每个线程可以独立执行一段代码,与其他线程并行运行。Java提供Thread类和Runnable接口来创建和管理线程。 2、创建线程 1)继承Thread类并重写run()方法: class MyThread extend Thread{ pub…...
本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——1到手测试
本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——1到手测试 大家好,今天给大家带来的是购买到小车或者说RDK X3之后直接快速体验,今天主要围绕官方的快速入门手册进行逐步测试 1.知识补充1 在这里首先要给新手小白补充几…...
2024第三届钉钉杯大学生大数据挑战赛【A题】完整分享
2024第三届钉钉杯大学生大数据挑战赛已经开赛,小编给大家带来非常实用的助力【A题】完整,(看图片下方的说明),资料预览: 微信公众号...
下面关于数组排序的说明那项是错误的?
下面关于数组排序的说明那项是错误的? A. java.util.Arrays类提供有数组排序的支持方法:sort(); B. 通过java.util.Arrays类排序的对象所在类需要实现Comparable或Comparator接口; C. String数组可以进行排序,是因为St…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
