C语言数据结构之堆排序

青衿之志

履践致远


堆排序(Heapsort) 是指利用 这种数据结构所设计的一种排序算法,它是 选择排序 的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆排降序建小堆

🎥二叉堆

🎥二叉树

🔥期待小伙伴们的支持与关注


目录

堆的创建 

 堆排序的实现

堆排序代码测试 

整体代码实现 

总结✨

稳定性

时间复杂度

空间复杂度

不适用于小数据集

堆的创建 

堆创建的方法

下面我们给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,现在我们通过算法,把它构建成一个堆。

 int a[] = {1,5,3,8,7,6};

我们一般采用 从下往上 建堆的方法,采用 向下调整 算法来建堆:

从倒数的 第一个非叶子节点的子树 开始调整,一直调整到 根节点 的树,就可以调整成堆

建堆的时间复杂度

因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了 简化 使用满二叉树来证明

叶子节点不需要堆化,所以需要堆化的节点从倒数第二层开始

每个节点堆化的过程中,需要 比较交换 的节点个数,跟这个节点的高度 h 成正比

我们只需要将 每个节点的高度求和 ,得出的就是建堆的时间复杂度

因为是 等比 数列,我们可以用  错位相减法 计算时间复杂度
所以建堆的时间复杂度为 O(n)
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{AdjustDown(arr, n, i);
}

这里的  (n - 1 - 1) / 2, n-1 表示下标,其次是套公式(child = parent * 2 + 1)

求出 第一个非叶子节点的子树 并开始向下调整

向下调整算法

void AdjustDown(int* data, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && data[child + 1] > data[child]){child++;}if (data[child] > data[parent]){Swap(&data[child], &data[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}

我们这里采用了 大根堆 的算法,目的是为了 排升序

为啥排升序需要大根堆呢?

 int a[] = {1,5,3,8,7,6};

我们还是以这个树为栗子

<1>我们可以先交换 堆顶数据堆末数据 ,在进行 向下调整 算法维护堆的性质

<2>因为这样升序待排数据就能先在数据末尾有序,并不断向前推进,最终有序

<3>如果我们采用的是小根堆,我们排的就是降序

结论:排升序建大堆 排降序建小堆

 这里给老铁们动图展示:

 堆排序的实现

void HeapSort(int* arr, int n)
{//建堆for (int i = (n - 1 - 1) / 2; i >= 0; i--){AdjustDown(arr, n, i);}//堆排序int len = n - 1;while (len){//堆顶数据和堆末数据交换Swap(&arr[0],& arr[len]);//维护树的性质AdjustDown(arr, len, 0);//剔除已排好的数据len--;}
}

堆排序代码测试 

int main(void)
{int arr[] = { 1,3,5,7,9,2,4,6,8,0 };HeapSort(arr, sizeof(arr) / sizeof(int));for (int i = 0; i < sizeof(arr) / sizeof(int); i++){printf("%d ", arr[i]);}printf("\n");system("pause");return 0;
}

整体代码实现 

#include<stdio.h>
#include<stdlib.h>
void Swap(int* n, int* m)
{int tmp = *n;*n = *m;*m = tmp;
}void AdjustDown(int* data, int n, int parent)
{int child = parent * 2 + 1;while (child < n){if (child + 1 < n && data[child + 1] > data[child]){child++;}if (data[child] > data[parent]){Swap(&data[child], &data[parent]);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);}int len = n - 1;while (len){Swap(&arr[0],& arr[len]);AdjustDown(arr, len, 0);len--;}
}int main(void)
{int arr[] = { 1,3,5,7,9,2,4,6,8,0 };HeapSort(arr, sizeof(arr) / sizeof(int));for (int i = 0; i < sizeof(arr) / sizeof(int); i++){printf("%d ", arr[i]);}printf("\n");system("pause");return 0;
}

总结✨

由于我们建堆的时间复杂度为 O(n)

排序的时间复杂度为 O(nlogn)

所以整体时间复杂度为O(nlogn)

稳定性

同选择排序一样,由于其中交换位置的操作,所以是不稳定的排序算法

时间复杂度

堆排序的最优时间复杂度、平均时间复杂度、最坏时间复杂度均为 O(nlogn)

空间复杂度

是一种原地排序算法,不需要额外的辅助存储空间,只需要原数组上进行元素的交换和调整

不适用于小数据集

堆排序的性能相对较好,但对于小规模的数据集来说,其常数项较大,不如快速排序等算法效率高

✨堆排序的主要优点在于它具有稳定的时间复杂度 O(nlogn),适用于大规模数据集的排序,而且是一种原地排序算法,不需要额外的空间。但它并不适用于小规模数据集,因为其常数项较大。堆排序也不是稳定排序,即相同值的元素在排序后的相对位置可能会改变。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

惰性删除、定期删除和Redis的淘汰策略有什么区别?

惰性删除&#xff08;Lazy Expiration&#xff09;和定期删除&#xff08;Periodic Expiration&#xff09;是Redis处理键过期的两种策略&#xff0c;它们共同作用以确保过期数据能够被有效地清理&#xff0c;但主要针对的是带有过期时间的键。 惰性删除&#xff1a; 当客户端尝…

sql面试题21:营销带货销量分析

题目大概意思&#xff1a; 找出网红带来的订单号和销售额&#xff08;销售额是该订单的&#xff0c;比如凑单&#xff09;&#xff0c;满足是优惠码是1的&#xff0c;B类商品 数据表两个&#xff0c;分别是订单和品类 CREATE TABLE 订单 (订单号 VARCHAR(512),商品号 VARCH…

常用的gpt网站

ChatGPT是一款基于人工智能技术的对话型AI助手&#xff0c;能够进行自然语言交互并提供个性化的对话服务。通过先进的深度学习模型&#xff0c;ChatGPT能够理解用户输入的文本&#xff0c;并生成有逻辑、连贯性的回复。它可以回答各种问题、提供建议、分享知识&#xff0c;还能…

如何使用US Domain Center和WordPress搭建非营利组织网站的详细指南

在今天的数字化时代&#xff0c;拥有一个专业、易于管理和更新的网站对于非营利组织&#xff08;例如慈善机构、NGO等&#xff09;至关重要。WordPress是一个功能强大且易于使用的网站构建平台&#xff0c;而美国域名中心 US Domain Center&#xff1a;US Domain Center 则是一…

如果需要在Log4j中记录特定的异常信息,应该如何实现?如何动态地更改Log4j的日志级别?

如果需要在Log4j中记录特定的异常信息&#xff0c;应该如何实现&#xff1f; 在Log4j中记录特定的异常信息&#xff0c;你可以使用Logger类的error、warn、info等方法&#xff0c;这些方法通常接受一个字符串消息和一个Throwable对象&#xff08;如异常&#xff09;作为参数。下…

嵌入式学习37-TCP并发模型

TCP并发模型: 1.TCP多线程模型: 缺点: 1.创建线程会带来 资源开销 2.能够实现的 并发量 比较有限 2.IO模型: 1.阻塞IO: 没有…

群晖NAS使用Docker安装WPS Office并结合内网穿透实现公网远程办公

文章目录 推荐1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff…

optee默认安全配置

OP-TEE&#xff08;Open Portable Trusted Execution Environment&#xff09;是一个开源的可移植的可信执行环境&#xff08;TEE&#xff09;&#xff0c;用于提供安全和受保护的执行环境。它旨在为基于 ARM 架构的设备提供强大的安全性和隔离能力。 OP-TEE 主要由两部分组成…

社交创新的先锋:探秘Facebook背后的故事与智慧

起源与初创阶段 Facebook的故事始于2004年&#xff0c;由马克扎克伯格&#xff08;Mark Zuckerberg&#xff09;、埃迪华索伦&#xff08;Eduardo Saverin&#xff09;、安德鲁麦克卡拉姆&#xff08;Andrew McCollum&#xff09;、克里斯休斯&#xff08;Chris Hughes&#x…

如何保证消息的顺序性

先看看顺序会错乱的场景&#xff1a;RabbitMQ&#xff1a;一个 queue&#xff0c;多个 consumer&#xff0c;这不明显乱了&#xff1a; 解决方案&#xff1a;

Qt/QML编程之路:openglwidget和倒车影像的切换(43)

关于如何实现一个基于OpenGL的3d 图形,这个有很多专门的介绍,我在开发中遇到了这么一个问题: 如何实现一个倒车影像的video显示与一个3D物体显示的切换,因为开窗在同样的一个位置,如果车子倒车启动,则需要将原本显示3D的地方切换为视频图像的显示。 class testOpenGl : …

高通芯片在车载系统上的主要功能?和NXP芯片的区别?

目录 高通芯片在车载系统上的主要功能&#xff1f; 高通芯片和NXP芯片的区别 高通芯片在车载系统上的主要功能&#xff1f; 高通芯片在车载信息娱乐系统&#xff08;IVI&#xff09;上的主要功能包括&#xff1a; 高性能计算&#xff1a;高通的骁龙汽车平台提供了强大的计算…

牛客网KY156 百鸡问题

题目 描述&#xff1a; 用小于等于n元去买100只鸡&#xff0c;大鸡5元/只&#xff0c;小鸡3元/只,还有1/3元每只的一种小鸡&#xff0c;分别记为x只,y只,z只。编程求解x,y,z所有可能解。 输入描述&#xff1a; 测试数据有多组&#xff0c;输入n。 输出描述&#xff1a; 对于每组…

Lucene 自定义词库

import org.apache.lucene.analysis.hunspell.Dictionary; import org.apache.lucene.analysis.hunspell.HunspellStemFilter; import

【办公类-22-13】周计划系列(5-5)“周计划-05 上传周计划png“ (2024年调整版本)

作品展示——将docx 转PDF转png&#xff0c;保留第一张图片 背景需求&#xff1a; 把周计划内容初步替换后&#xff0c;获得了19周的周计划教案的docx 需要把周计划第一页的反思内容删除&#xff0c;&#xff0c;然后把第一页横版截图上传班级主页。 需求&#xff1a;周计划do…

98. 一台服务器能支持多少QPS

一台服务器能够支持的QPS(Queries Per Second)数量是一个很常见的问题。这是因为,当我们在设计和部署一个应用程序的时候,我们需要确保它能够处理足够的流量,以满足用户的需求。 在本文中,我们将探讨如何计算一台服务器能够支持的QPS。 计算一台服务器的QPS 首先,我们需要了解…

云桥通SDWAN企业组网的15大应用场景

云桥通SD-WAN企业组网技术在企业网络中有多样化的应用场景&#xff0c;在技术不断迭代升级中&#xff0c;已经越来越匹配现在的互联网环境&#xff0c;其中在这15中常见的应用场景中&#xff0c;使用云桥通SDWAN企业组网可以很好的帮到企业&#xff1a; 分支机构连接优化&#…

C#判断素数的方法:试除法 vs 优化的试除法 vs 米勒-拉宾素数检测算法

目录 1.素数也就质数 2. 试除法 3.优化的试除法_1 4.优化的试除法_2 5.优化的试除法_3 6.米勒-拉宾素数检测算法 1.素数也叫质数 一个质数是一个大于1的自然数&#xff0c;只有两个正因数&#xff1a;1和它自身。这意味着如果一个数只有两个正因数&#xff0c;那么它就是…

#QT(QSpinBox,QDoubleSpinBox)

1.IDE&#xff1a;QTCreator 2.实验:实现一个计价工具&#xff0c;进制转换工具。 教程来自&#xff1a;阿西拜编程 QT C 5.9 3.记录 设置进制的第二种方法 ui->hex_tx->setDisplayIntegerBase(16); //设置显示进制为16进制 4.代码 widget.cpp #include "wi…

做一下笔记 CXDB5CCAM-MK 与 CXDBCCAM-ML 的区别

1. CXDB5CCAM-MK 的简介 2. CXDBCCAM-ML 的简介 3. 这个两个器件的区别 最基本可见的区别是 &#xff1a; 传输速度的不同。 4. 资料在资源里面