当前位置: 首页 > news >正文

【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语言】堆排序

堆排序即利用堆的思想来进行排序&#xff0c;总共分为两个步骤&#xff1a; 1. 建堆 升序&#xff1a;建大堆 降序&#xff1a;建小堆 原因分析&#xff1a; 若升序建小堆时间复杂度是O(N^2) 升序建大堆&#xff0c;时间复杂度O&#xff08;N*logN&#xff09; 所以升序建大堆…...

ntp服务重启报错Failed to restart ntpd.service: Unit is masked.

问题概述&#xff1a; 重启ntp服务报错Failed to restart ntpd.service: Unit is masked&#xff0c;使用systemctl unmask ntpd.service命令关闭屏蔽还是报错Failed to restart ntpd.service: Unit is masked 解决方法&#xff1a; 重装ntp服务 yum remove ntpyum install…...

面试题-每日5到

16.Files的常用方法都有哪些&#xff1f; Files.exists():检测文件路径是否存在 Files.createFile():创建文件 Files.createDirectory():创建文件夹 Files.delete():删除一个文件或目录 Files.copy():复制文件 Files.move():移动文件 Files.size():查看文件个数 Files.read():读…...

代码美学大师:打造Perl中的个性化代码格式化工具

代码美学大师&#xff1a;打造Perl中的个性化代码格式化工具 在软件开发过程中&#xff0c;代码的可读性至关重要。Perl&#xff0c;作为一种灵活的脚本语言&#xff0c;允许开发者以多种方式实现代码格式化。自定义代码格式化工具不仅能提升代码质量&#xff0c;还能加强团队…...

成为一名月薪 2 万的 web 安全工程师需要掌握哪些技能?

现在 web 安全工程师比较火&#xff0c;岗位比较稀缺&#xff0c;现在除了一些大公司对学历要求严格&#xff0c;其余公司看中的大部分是能力。 有个亲戚的儿子已经工作 2 年了……当初也是因为其他的行业要求比较高&#xff0c;所以才选择的 web 安全方向。 资料免费分享给你…...

Linux中如何添加磁盘分区

在Linux中添加分区通常涉及到几个步骤&#xff0c;包括识别磁盘、创建分区、格式化分区&#xff0c;以及挂载或将其用作特定的文件系统类型&#xff08;如LVM、RAID等&#xff09;。以下是一个基本的步骤指南&#xff0c;假设你正在使用命令行界面&#xff08;CLI&#xff09;和…...

计算机毕业设计Hadoop+Hive专利分析可视化 面向专利的大数据管理系统 专利爬虫 专利数据分析 大数据毕业设计 Spark

《Hadoop专利大数据分析可视化系统》开题报告 一、选题背景与意义 随着信息技术的飞速发展&#xff0c;全球数据量呈现爆炸式增长&#xff0c;特别是在专利领域&#xff0c;数据的积累和更新速度更是惊人。专利数据不仅包含了技术创新的详细信息&#xff0c;还反映了行业的发…...

git是什么?git和svn的区别。git的一些命令

Git是什么 Git是一个开源的分布式版本控制系统&#xff08;Distributed Version Control System&#xff0c;简称DVCS&#xff09;&#xff0c;它可以有效、高速地处理从很小到非常大的项目版本管理。版本控制系统能追踪项目从开始到结束的整个过程&#xff0c;对编程人员而言…...

RK3568平台(触摸篇)双屏异触调试

一.现象 现象&#xff1a;准备两块主屏都接触摸框&#xff0c;A屏的HDMIOUT外接B屏的HDMIIN&#xff0c;用手触摸A屏&#xff0c;发现A屏没有触摸&#xff0c;A屏幕的触摸现象在B屏那边。 现要求&#xff1a;用手触摸A屏&#xff0c;A屏要有现象&#xff0c;不能现象在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扫描&#xff0c;发现源文件index.php.bak 下载下来 打开文件 代码审计&#xff0c;翻译一下 翻译代码为&#xff1a; <?php include_once "flag.php"; //这一行使用 include_once 函数来包含&#xff08;或插入&#xff09;另一个 PHP …...

Springboot学习-day16

Springboot学习-day16 Springboot是spring家族中的一个全新框架&#xff0c;用来简化spring程序的创建和开发过程。在以往我们通过SpringMVCSpringMybatis框架进行开发的时候&#xff0c;我们需要配置web.xml&#xff0c;spring配置&#xff0c;mybatis配置&#xff0c;然后整…...

Map 31

...

dfs,CF 196B - Infinite Maze

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 https://codeforces.com/problemset/problem/196/B 二、解题报告 1、思路分析 考虑如何判断一条路径可以无限走&#xff1f; 我们对朴素的网格dfs改进&#xff0c;改进为可以dfs网格外的区域 如果存在某个…...

鸿蒙应用框架开发【JS注入与执行】 Web

JS注入与执行 介绍 本示例基于H5游戏&#xff0c;通过arkui的button实现对游戏实现基本控制&#xff0c;展示webview的JS注入与执行能力&#xff0c;及native应用与H5的通信能力。 效果预览 使用说明 1.设备连接热点&#xff0c;可访问互联网。 2.打开应用&#xff0c;通过…...

AI问答:理解 DRG / Diagnosis Related Group / 按疾病诊断相关分组

DRG&#xff08;Diagnosis Related Group&#xff09;系统&#xff0c;中文译作“按疾病诊断相关分组”&#xff0c;是一种根据病情临床相似程度和资源消耗水平将住院病人进行分组的系统。以下是对DRG系统的详细理解&#xff1a; 一、定义与原理 1.1、定义&#xff1a;DRG系统…...

多个线程同时调用接口

1、线程的基本概念 线程是程序执行的最小单元。每个线程可以独立执行一段代码&#xff0c;与其他线程并行运行。Java提供Thread类和Runnable接口来创建和管理线程。 2、创建线程 1&#xff09;继承Thread类并重写run()方法&#xff1a; class MyThread extend Thread{ pub…...

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——1到手测试

本科阶段最后一次竞赛Vlog——2024年智能车大赛智慧医疗组准备全过程——1到手测试 ​ 大家好&#xff0c;今天给大家带来的是购买到小车或者说RDK X3之后直接快速体验&#xff0c;今天主要围绕官方的快速入门手册进行逐步测试 1.知识补充1 ​ 在这里首先要给新手小白补充几…...

2024第三届钉钉杯大学生大数据挑战赛【A题】完整分享

2024第三届钉钉杯大学生大数据挑战赛已经开赛&#xff0c;小编给大家带来非常实用的助力【A题】完整&#xff0c;&#xff08;看图片下方的说明&#xff09;&#xff0c;资料预览&#xff1a; 微信公众号...

下面关于数组排序的说明那项是错误的?

下面关于数组排序的说明那项是错误的&#xff1f; A. java.util.Arrays类提供有数组排序的支持方法&#xff1a;sort()&#xff1b; B. 通过java.util.Arrays类排序的对象所在类需要实现Comparable或Comparator接口&#xff1b; C. String数组可以进行排序&#xff0c;是因为St…...

【第二篇章】优秀的机器学习策略 超参数优化之决策树

在机器学习的浩瀚星空中&#xff0c;决策树作为一颗璀璨的星辰&#xff0c;以其直观易懂、解释性强以及高效处理分类与回归任务的能力&#xff0c;赢得了众多数据科学家与工程师的青睐。随着大数据时代的到来&#xff0c;如何从海量数据中提炼出有价值的信息&#xff0c;构建出…...

httprunner转载

基于 HttpRunner4.0 的接口自动化测试实践 测试之家 from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase # 配置数据库连接信息 config ( Config("database test") .variables( **{ "db_host": &…...

反序列化漏洞vulhub靶场serial

环境搭建 下载 https://download.vulnhub.com/serial/serial.zip 解压出来就是这种 你会得到一个这样的文件&#xff0c;这里使用VMware新建一个虚拟机&#xff0c;这里记录比较重要的几部分。 这里就是使用我们刚才下过来的。 漏洞过程详解 1.信息收集 打开靶机&#xff0…...

C++ 文件流详解

在 C 中&#xff0c;文件处理是一个常见且重要的任务。标准库提供了三种主要的文件流类来处理文件输入和输出&#xff1a;fstream、ifstream 和 ofstream。这些类都在 <fstream> 头文件中定义。 一、fstream 类 fstream 是文件流类的基类&#xff0c;既可以用于读操作&…...

docker compse简介与安装

目录 1. Docker Compose 简介 2. Docker Compose 安装 2.1 在 Ubuntu 上安装 Docker Compose 2.1.1 通过 apt 安装 2.1.2 使用官方脚本安装最新版本 2.2 在 CentOS 上安装 Docker Compose 2.2.2 使用官方脚本安装最新版本 2.2.3 使用 pip 安装 2.3 在 openEuler 上安装…...

基于深度学习的零样本学习

零样本学习&#xff08;Zero-Shot Learning, ZSL&#xff09;是深度学习中的一个前沿研究领域&#xff0c;其目标是在没有见过目标类别的样本的情况下&#xff0c;对这些新类别进行识别或分类。这种方法特别适用于在实际应用中存在大量未标注类别或新类别不断涌现的场景&#x…...

C++——list容器以及手动实现

LIST容器 list概述列表容器属性例子 list函数构造函数默认构造函数&#xff1a;带有元素个数和元素初值的构造函数&#xff1a;范围构造函数&#xff1a;拷贝构造函数&#xff1a;移动构造函数&#xff1a;示例 赋值运算符重载拷贝赋值操作符 (1)&#xff1a;移动赋值操作符 (2…...

Win11系统文件资源管理器鼠标右键卡顿解决方法

引用链接&#xff1a; Windows 11文件资源管理器崩溃怎么解决&#xff1f;看看这7个解决办法&#xff01;...

零基础学Python之 第十八讲 文件读写

当你开始学习Python编程时&#xff0c;文件读写是一个非常基础且重要的技能。本篇博客将引导你从零开始学习如何在Python中进行文件读写操作。 1. 打开文件 在Python中&#xff0c;要操作一个文件&#xff0c;首先需要打开它。使用内置的 open() 函数来打开文件&#xff0c;语…...

检索增强生成(RAG):智能内容生成的新纪元

引言 在大 AI 时代&#xff0c;生成式人工智能&#xff08;GenAI&#xff09;模型&#xff0c;尤其是大型语言模型&#xff08;LLM&#xff09;&#xff0c;已经展现出了令人瞩目的能力。然而&#xff0c;这些模型在提供信息的准确、即时、专业、权威等方面仍存在局限。检索增…...

java编程做网站/营销推广方式

第一种方法&#xff1a;新建一个文本文件&#xff0c;输入以下内容 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\lnkfile] "IsShortcut""" 然后另存为&#xff0c;将文件名给为one.reg&#xff0c;文件类型更改为所有文件&#xff0c;然后双…...

宁波网站开发公司电话/电商最好卖的十大产品

二叉树一般都是和递归有联系的&#xff0c;二叉树的遍历包括了前序&#xff0c;后序&#xff0c;中序&#xff0c;大部分题目只要考虑清楚应该用那种遍历顺序&#xff0c;然后特殊情况的条件&#xff0c;题目就会迎刃而解。 1. 先来说说二叉树的遍历方式 其实二叉树的遍历很简…...

做网站的动态图片/苏州网站优化公司

文章目录一、循环语句1.1 for循环语句1.1.1 for语句的结构1.1.2 for语句应用示例1.2 while循环语句1.3 until循环语句1.3.1 until语句的结构二、 Shell函数2.1 Shell函数2.1 函数应用示例2.2 函数的作用范围2.3 函数的参数2.4 递归函数三、 Shell数组3.1 Shell数组3.2 Shell脚本…...

专做日淘的网站/最近三天的新闻大事摘抄

※ 写在前面Hi 各位&#xff0c;是我旅客君&#xff0c;又和大家见面了&#xff0c;大家还记得之前 MacBook 的体验评测吗&#xff1f;非常感谢大家对我的支持&#xff0c;这次就继续为大家带来这台 MacBook Pro 搭配显卡扩展坞的体验评测。如果还没有看过的可以先点击一下这个…...

iis 新建网站/seo关键词排名优化是什么

大家好&#xff01; 这是我第二次写随笔感想&#xff0c;有不足之处希望大家提出&#xff0c;我也算的上一个小白&#xff0c;自己进入前端行业也刚刚半年&#xff0c;在这里半年里我遇到一个技术大牛的好领导&#xff0c;让我在项目中学到很多&#xff0c;想和大家分享一下&am…...

湛江电气建站软件/百度入口网页版

默认情况下&#xff0c;Graphics 绘图类使用的笔画属性是粗细为1个像素的正方形&#xff0c;而Java2D的Graphics2D类可以调用setStroke()方法设置笔画的属性&#xff0c;如改变线条的粗细、虚实和定义线段端点的形状、风格等。语法如下&#xff1a;setStroke(Stroke stroke)其中…...