堆排序(C语言版)
一.堆排序
1.1.利用上下调整法实现堆排序
第一步:建堆
好了,每次建堆都要问自己下,要建的是什么堆?大堆还是小堆呢?
我们这里就一一来实现,先建大堆
void Print(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}
void Swap(int* p1, int* p2)
{int* tmp = *p1;* p1=*p2;*p2 = tmp;
}
void Adjustup(int* arr2, int child)
{int parent = (child - 1) / 2;while (child > 0){if (arr2[child]>arr2[parent])//注意我们是建的大堆{Swap(&arr2[child], &arr2[parent]);//传地址才能改变值child = parent;parent = (child - 1) / 2;}else{break;}}
}
void Heapsort(int* arr, int n)
{//建立堆//问题是:你是建大堆还是小堆?//我们这里要建大堆for (int i = 1; i < n; i++){Adjustup(arr, i);//利用向上调整法}Print(arr,n);
}
如果你实现过堆的代码相信上面的代码对你来说绝对小菜一碟
由于我们直接调用了打印函数,那么我们来看看结果吧。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Print(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}
void Swap(int* p1, int* p2)
{int* tmp = *p1;* p1=*p2;*p2 = tmp;
}
void Adjustup(int* arr2, int child)
{int parent = (child - 1) / 2;while (child > 0){if (arr2[child]>arr2[parent])//注意我们是建的大堆{Swap(&arr2[child], &arr2[parent]);//传地址才能改变值child = parent;parent = (child - 1) / 2;}else{break;}}
}
void Heapsort(int* arr, int n)
{//建立堆//问题是:你是建大堆还是小堆?//我们这里要建大堆for (int i = 1; i < n; i++){Adjustup(arr, i);//利用向上调整法}Print(arr,n);
}
int main()
{int arr[] = { 4,6,2,1,5,8,2,9 };int sz = sizeof(arr) / sizeof(int);Heapsort(arr, sz);return 0;
}
结果:
这个是不是就满足了大堆
第二步:如何实现排序呢?(别看上面是从大到小排好的,这只是一个巧合,我们要学会正确的排序法)
如果你对此不清楚,那么我要开始表演了。
如果你想,我们是大堆,这说明最大的数即是堆顶,如果我交换数组首尾位置,然后这是不是不再是一颗完全二叉树了,那么如果我再通过向下调整法来排好,重复操作,是不是就会得到一个从小到大的数组,那么不就排好序了,想到这,相信你肯定联想到了堆的删除操作,下面就让我们利用堆的删除来实现它吧!
void Swap(int* p1, int* p2)
{int* tmp = *p1;* p1=*p2;*p2 = tmp;
}
void Adjustdown(int* arr3, int n, int parent)
{int child = parent * 2 + 1;//假设左孩子大//注意我们建的是大堆while (child < n){if ((child + 1) < n && (arr3[child] < arr3[child + 1])){child++;}if (arr3[parent] < arr3[child]){Swap(&arr3[parent], &arr3[child]);//交换父子位置parent = child;child = parent * 2 + 1;}else{break;}}
}//堆建好了,现在实现第二步:堆删除
int end = n - 1;
while (end > 0)
{//堆删除分以下几步://第一步:首尾元素互换Swap(&arr[0], &arr[end]);//第二步:向下调整法调整树根Adjustdown(arr, end, 0);//第三步:删除堆尾end--;
}
这对于学过实现堆的你来说依然so easy。
那么就让我们整体检查代码的正确性:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Print(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}
void Swap(int* p1, int* p2)
{int* tmp = *p1;* p1=*p2;*p2 = tmp;
}
void Adjustup(int* arr2, int child)
{int parent = (child - 1) / 2;while (child > 0){if (arr2[child]>arr2[parent])//注意我们是建的大堆{Swap(&arr2[child], &arr2[parent]);//传地址才能改变值child = parent;parent = (child - 1) / 2;}else{break;}}
}
void Adjustdown(int* arr3, int n, int parent)
{int child = parent * 2 + 1;//假设左孩子大//注意我们建的是大堆while (child < n){if ((child + 1) < n && (arr3[child] < arr3[child + 1])){child++;}if (arr3[parent] < arr3[child]){Swap(&arr3[parent], &arr3[child]);//交换父子位置parent = child;child = parent * 2 + 1;}else{break;}}
}
void Heapsort(int* arr, int n)
{//建立堆//问题是:你是建大堆还是小堆?//我们这里要建大堆for (int i = 1; i < n; i++){Adjustup(arr, i);//利用向上调整法}Print(arr,n);//堆建好了,现在实现第二步:堆删除int end = n - 1;while (end > 0){//堆删除分以下几步://第一步:首尾元素互换Swap(&arr[0], &arr[end]);//第二步:向下调整法调整树根Adjustdown(arr, end, 0);//第三步:删除堆尾end--;}Print(arr, n);
}
int main()
{int arr[] = { 4,6,2,1,5,8,2,9 };int sz = sizeof(arr) / sizeof(int);Heapsort(arr, sz);return 0;
}
结果:
如果你是要从大到小排序,操作如下:
建小堆-》堆的尾删
整体而言有三处改动:
1.在void Adjustup(int* arr2, int child)函数中这个语句要改变符号,因为是建小堆了。
if (arr2[child]>arr2[parent])//
2.在void Adjustdown(int* arr3, int n, int parent)这个函数中这两处符号也要改变,原因是因为你现在是小堆,向下调整法肯定要调整
if (arr3[child] < arr3[child + 1]))
if (arr3[parent] < arr3[child])
整体如下:
//表示原来的语句//arr2[child]>arr2[parent]
arr2[child]<arr2[parent]//if ((child + 1) < n && (arr3[child] < arr3[child + 1]))
if ((child + 1) < n && (arr3[child] > arr3[child + 1]))//if (arr3[parent] < arr3[child])
if (arr3[parent] > arr3[child])
改完之后结果如下:
现在我们就要对这个算法进行分析:
时间复杂度:建堆为O(NlogN)+选数O(N-1logN)
得出结果:O(NlogN)(非常牛逼的算法)
1.2.只利用向下调整法实现堆排序
大家看上面的代码是不是感觉一个排序要写这么麻烦好不方便啊,是的,我们其实可以只通过一个向下调整就可以实现堆排序,下面看看我的表演吧!
步骤还是和上面一样,其实就改变了建堆的过程,我们现在是通过向下调整法建堆。
看代码:
for (int i = ; i ; i)
{Adjustdown(arr,,);
}
我们就是要把上面的空缺填好,那么该如何写呢?
我要告诉你一个概念:向下调整建堆是从第一个非叶子节点开始调整,我们肯定要调整到0
所以我们可以这样写:
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{Adjustdown(arr,n,i);
}
其他部分不用改变,所以整体代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Print(int* arr, int n)
{for (int i = 0; i < n; i++){printf("%d ", arr[i]);}printf("\n");
}
void Swap(int* p1, int* p2)
{int* tmp = *p1;* p1=*p2;*p2 = tmp;
}
void Adjustdown(int* arr3, int n, int parent)
{int child = parent * 2 + 1;//假设左孩子大//注意我们建的是大堆while (child < n){if ((child + 1) < n && (arr3[child] < arr3[child + 1])){child++;}if (arr3[parent] < arr3[child]){Swap(&arr3[parent], &arr3[child]);//交换父子位置parent = child;child = parent * 2 + 1;}else{break;}}
}
void Heapsort(int* arr, int n)
{for (int i = (n - 1 - 1) / 2; i >= 0; i--){Adjustdown(arr,n,i);}Print(arr, n);//堆建好了,现在实现第二步:堆删除int end = n - 1;while (end > 0){//堆删除分以下几步://第一步:首尾元素互换Swap(&arr[0], &arr[end]);//第二步:向下调整法调整树根Adjustdown(arr, end, 0);//第三步:删除堆尾end--;}Print(arr, n);
}
int main()
{int arr[] = { 4,6,2,1,5,8,2,9 };int sz = sizeof(arr) / sizeof(int);Heapsort(arr, sz);return 0;
}
结果:
来我们该讨论该算法时间复杂度情况了
建堆O(N)+选数O(NlogN)
时间复杂度:O(N*logN)
注意:该写法不仅简单(比上面那种),而且效率也比上面的高。
相关文章:

堆排序(C语言版)
一.堆排序 堆排序即利用堆的思想来进行排序,总共分为两个步骤: 1. 建堆 升序:建大堆 降序:建小堆 2. 利用堆删除思想来进行排序 1.1.利用上下调整法实现堆排序 第一步:建堆 好了,每次建堆都要问自己…...

实现区域地图散点图效果,vue+echart地图+散点图
需求:根据后端返回的定位坐标数据实现定位渲染 1.效果图 2.准备工作,在main.js和index.js文件中添加以下内容 main.js app.use(BaiduMap, {// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */ak: sRDDfAKpCSG5iF1rvwph4Q95M…...

Kubernetes 学习总结(41)—— 云原生容器网络详解
背景 随着网络技术的发展,网络的虚拟化程度越来越高,特别是云原生网络,叠加了物理网络、虚机网络和容器网络,数据包在网络 OSI 七层网络模型、TCP/IP 五层网络模型的不同网络层进行封包、转发和解包。网络数据包跨主机网络、容器…...

多人协同开发git flow,创建初始化项目版本
文章目录 多人协同开发git flow,创建初始化项目版本1.gitee创建组织模拟多人协同开发2.git tag 打标签3.git push origin --tags 多人协同开发git flow,创建初始化项目版本 1.gitee创建组织模拟多人协同开发 组织中新建仓库 推送代码到我们组织的仓库 2…...

「Kafka」入门篇
「Kafka」入门篇 基础架构 Kafka 快速入门 集群规划 集群部署 官方下载地址:http://kafka.apache.org/downloads.html 解压安装包: [atguiguhadoop102 software]$ tar -zxvf kafka_2.12-3.0.0.tgz -C /opt/module/修改解压后的文件名称: [a…...

PHP8的JIT(Just-In-Time)编译器是什么?
PHP8的JIT(Just-In-Time)编译器是什么? PHP8是最新的PHP版本,引入了JIT(Just-In-Time)编译器,以进一步提高性能和执行速度。 JIT编译器是一种在运行时将解释性语言转化为机器码的技术。在过去…...

【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数
文章目录 🚀前言🚀C有何过C之处?🚀C中的关键字🚀命名空间✈️为什么要引入命名空间?✈️命名空间的定义✈️如何使用命名空间中的内容呢? 🚀C中的输入和输出✈️C标准库的命名空间✈…...

Excel中部分sheet页隐藏并设置访问密码
1、新建sheet1 2、新建sheet2 3、隐藏sheet2 4、保护工作簿、输密码 5、密码二次确认 6、隐藏的sheet2已经查看不了 7、想要查看时,按图示输入原密码即可 8、查看sheet2内容...

从零开始配置pwn环境:CTF PWN 做题环境
前期在kali2023环境安装的pwndocker使用发现不好用,so找了网上配置好pwn环境的虚拟机。 GitHub - giantbranch/pwn-env-init: CTF PWN 做题环境一键搭建脚本 可以直接下载我配置好的Ubuntu 16.04,为VMware导出的ovf格式 链接:百度网盘 请输…...

Vue3复习笔记
目录 挂载全局属性和方法 v-bind一次绑定多个值 v-bind用在样式中 Vue指令绑定值 Vue指令绑定属性 动态属性的约束 Dom更新时机 ”可写的“计算属性 v-if与v-for不建议同时使用 v-for遍历对象 数组变化检测 事件修饰符 v-model用在表单类标签上 v-model还可以绑定…...

【OpenCV】OpenCV:计算机视觉的强大工具库
摘要 OpenCV是一个广泛应用于计算机视觉领域的开源工具库,为开发者提供了丰富的图像处理和计算机视觉算法。本文将介绍OpenCV的功能和应用领域,并探讨它在实践中的重要性和前景。 计算机视觉的强大工具库 一、什么是OpenCV?二、OpenCV的功…...

spring-boot-autoconfigure误引入spring-boot-starter-data-jpa而导致数据源初始化异常
一、现状描述 某个Grade类引入了jpa的注解: import javax.persistence.Column; import javax.persistence.Embeddable;/*** 年级*/ Embeddable public class Grade {Column(name "code")private int code; }并且pom.xml中引入该jar包:sprin…...

工程(十六)——自己数据集跑Fast_livo
一、基础环境 Ubuntu20.04 ROS noetic PCL 1.8 Eigen 3.3.4 Sophus git clone https://github.com/strasdat/Sophus.git cd Sophus git checkout a621ff mkdir build && cd build && cmake .. make sudo make install 下面两个直接把包下载下来一起编译…...

PostgreSQL数据库的json操作
1.操作符 select json字段::json->key值 from order -- 对象域 select json字段::json->>key值 from order -- 文本 select json字段::json#>{key值} from order -- 对象域 select json字段::json#>>{key值} from order -- 文本对象域表示还能继续操作&#…...

gradio-osprey-demo
创建需要的dockerfle ################### # 使用 Ubuntu 作为基础镜像 FROM nvcr.io/nvidia/cuda:11.8.0-devel-ubuntu22.04 # 更新软件包列表并安装依赖项 RUN apt update && \ apt install -y python3 python3-pip git ffmpeg libsm6 libxext6 curl wget …...

从仿写持久层框架到MyBatis核心源码阅读
接上篇手写持久层框架:https://blog.csdn.net/liwenyang1992/article/details/134884703 MyBatis源码 MyBatis架构原理&主要组件 MyBatis架构设计 MyBatis架构四层作用是什么呢? API接口层:提供API,增加、删除、修改、查询…...

浏览器常用基本操作之python3+selenium4自动化测试
1、打开指定的网页地址 我们使用selenium进行自动化测试时,打开浏览器之后,第一步就是让浏览器访问我们指定的地址,可使用get方法实现 1 2 3 from selenium import webdriver driver webdriver.Edge() driver.get(https://www.baidu.com/)…...

在MySQL中使用VARCHAR字段进行日期筛选
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...

微信小程序自定义步骤条效果
微信小程序自定义一个步骤条组件,自定义文字在下面,已完成和未完成和当前进度都不一样的样式,可点击上一步和下一步切换流程状态,效果如下。 这是视频效果: 前端实现步骤条效果 下面我们一步步实现编码,自定…...

QT的信号与槽
QT的信号与槽 文章目录 QT的信号与槽前言一、QT 打印"hello QT"的dome二、信号和槽机制?二、信号与槽的用法1、QT5的方式1. 无参的信号与槽的dome2.带参的信号与槽dome 2、QT4的方式3、C11的语法 Lambda表达式1、函数对象参数2、操作符重载函数参数3、可修…...

Python 为UnityAndroid端自动化接入Tradplus广告SDK
Python 为UnityAndroid端自动化接入Tradplus广告SDK Tradplus介绍常规接入进入Android开发文档选择渠道配置生成接入代码人工依赖下载官网同版本的 Unity插件 使用自动化工具接入首次 你需要打两个标记来定位运行工具 控制台会列出最新的十个Tradplus版本 任选其一然后拖入项目…...

Matplotlib基础
目录: 一、绘制yx^2图像: 一、绘制yx^2图像: from matplotlib import pyplot as plt import numpy as np #生成(-50,50)的数组 x np.arange(-50,50) #计算因变量y的值 y x ** 2 #根据x、y数组绘制图形yx^2 plt.plot…...

上海东海职业技术学院低代码实训平台建设项目竞争性磋商公告
上海东海职业技术学院低代码实训平台建设项目竞争性磋商公告 招标|招标公告 上海市|闵行区 项目编号:0773-2340GNSHFWCS2823 招标单位:上海东海职业技术学院 代理单位:中金招标有限责任公司 预算金额:59万元 联系方式&…...

c语言之将输入的十进制转换成二进制数并打印原码反码补码
十进制转二进制 首先,我们要知道的是十进制转换成二进制数的方法。我们一般采用的除二取余的方法,在这里我用32位数组来进行转换。 int main() {printf("请输入一个十进制数\n");int n 0;scanf("%d", &n);int arr[32];int* p…...

算法题明明的随机数
第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。 import java.util.Iterator; import java.util.Scanner; import java.util.TreeSet; // 注意类名必须为 Main, 不要有任何 pa…...

B站不赚钱、“芒果”赚钱难,视频“后浪”火拼跨年夜
又是一年跨年时。 各大视频平台跨年晚会展开火拼,今年谁是赢家? 作为视频“后浪”,芒果超媒(300413.SZ)、哔哩哔哩(09626.HK,下称“B站”)此前相继公布了2023年三季报,…...

ajax请求的详细流程+详细示例
AJAX(Asynchronous JavaScript and XML)是一种用于创建异步 Web 应用程序的技术。下面是 AJAX 请求的详细流程: 创建 XMLHttpRequest 对象:在 JavaScript 代码中,使用 new XMLHttpRequest() 创建一个 XMLHttpRequest 对…...

这些产品手册制作工具,你都值得收藏
产品手册是企业向消费者传达产品信息的重要媒介,它能够直接影响消费者对产品的了解和购买决策。然而,制作一份专业而吸引人的产品手册并非易事,需要一定的设计和排版能力。为了帮助企业和个人更轻松地制作出优质的产品手册,下面将…...

跨账号和同账号的ECS云服务器之间迁移教程
阿里云ECS实例间迁移场景如下: 场景一:跨账号ECS实例间迁移 此场景适用于跨账号,同地域或者跨地域下的ECS实例间的迁移。例如:将阿里云账号A下的ECS实例,迁移阿里云B账号下。 场景二:同账号ECS实例间迁移 …...

python virtualenv 虚拟环境命令
# 安装 virtualenv pip3.9 install virtualenv # 创建虚拟环境test mkdir /envs # 创建一个文件夹放置虚拟环境 cd /envs/ virtualenv /envs/test # --pythonpython3.9 # 激活虚拟环境test source /envs/test/bin/activate # 安装依…...