堆排序详解

堆:是一种特殊的完全二叉树,一般通过顺序表存储,分为大堆和小堆两类。

大堆:父节点的值恒大于子节点的值。

小堆:父节点的值恒小于子节点的值。

创建堆,可以使得根节点成为整个堆中保存最大或最小的值的结,根据这个特性,堆可以用于排序和解决TopK问题。

创建堆:

方法一:向上排序法

原理:对由前k个结点构成的堆,插入第k+1个结点到最后,然后不断与其父节点进行比对,符合条件就互换,不符合条件就留在原地结束循环。循环结束后,前k+1个结点仍是堆。

时间复杂度:O(nlogn)

方法二:向下排序

原理:首先创造一个完全二叉树,然后从倒数第二层最后一个结点开始,不断以当前结点为根节点创建堆,直至最后以根节点创建堆。每次创建堆,都是先比较该结点的子节点,找出更可能上移的结点,然后与父节点比较,符合条件就互换,然后继续该步骤,不符合条件就停止循环。循环结束后,该部分就成为了一个堆。

时间复杂度:O(N)

堆排序:

思路:将根节点与最后一个结点互换,使得最后一个结点永远保存当前最大(小)的结点,然后对互换后的根节点进行向下排序,使得排完序列后整个二叉树仍然是堆,再将新的根节点与倒数第二个结点互换,重复上述操作。最后,整个堆就是一个升序或降序的顺序表。

时间复杂度:O(NlogN)

每个根节点最多移动logN次,一共N-1个结点进行移动,因此时间复杂度是NlogN。

具体代码实现:

void swap1(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void up_insert1(HPDataType* a, int i)
{int child = i;int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){swap1(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}
void down_insert1(HPDataType* a, int n, int i)
{int parent = i;int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child++;}if (a[parent] > a[child]){swap1(&a[parent], &a[child]);parent = child;child = child * 2 + 1;}else{break;}}}
void HeapSort(int* a, int n)
{//创建堆for (int i = 1; i < n; i++){up_insert1(a, i);}测试//for (int i = 0; i < n; i++)//{//	printf("%d ", a[i]);//}//printf("\n");//排序for (int i = 0; i < n; i++){swap1(&a[0], &a[n - 1-i]);down_insert1(a, n - i - 1, 0);}//测试for (int i = 0; i < n; i++){printf("%d ", a[i]);}printf("\n");}

TopK问题:

问题要求:对N个数据,只取最大(或最小)的前k个。

思路:先用前k个数据创建堆,此处要求取最大的前k个,则创建小堆。

创建小堆后根元素为整个堆中最下的元素,新的元素若比根节点大则替换根节点,然后进行向下排序,使得整个二叉树仍然为堆。进行N-k次上述操作,得到的堆就会保存最大的前k个元素。

具体代码:

void CreateNDate()
{// 造数据int n = 10000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (size_t i = 0; i < n; ++i){int x = rand() % 1000000;fprintf(fin, "%d\n", x);}fclose(fin);
}
void swap1(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}
void down_insert1(HPDataType* a, int n, int i)
{int parent = i;int child = parent * 2 + 1;while (child < n){if (child + 1 < n && a[child] > a[child + 1]){child++;}if (a[parent] > a[child]){swap1(&a[parent], &a[child]);parent = child;child = child * 2 + 1;}else{break;}}}
void PrintTopK(int k)
{const char* file = "data.txt";FILE* fin = fopen(file, "r");//创建小堆  (找最大的前k个)int* arr = (int*)malloc(sizeof(int) * k);if (arr == NULL){perror("malloc");exit(-1);}int i = 0;int num = k;while (num--){fscanf(fin, "%d\n", &arr[i]);i++;}Heap hp;HeapCreate(&hp, arr, k);//插入其余元素int x = 0;int count = 0;while (fscanf(fin, "%d\n", &x) != EOF){   /*	if (count % 1000 == 0){x *= 1000;}*/if (x > hp.a[0]){hp.a[0] = x;down_insert1(hp.a, k, 0);}}printf("插入成功\n");//测试for (int j = 0; j < k; j++){printf("%d  ",hp.a[j]);}printf("\n");}

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

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

相关文章

基于jeecg-boot的flowable流程历史记录显示修改

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/nbcio-boot 前端代码&#xff1a;https://gitee.com/nbacheng/nbcio-vue.git 在线演示&#xff08;包括H5&#xff09; &#xff1a; http://122.227.135.243:9888 历…

MySQL和Oracle数据库引擎

MYSQL数据库&#xff1a; 在mysql数据库中&#xff0c;常用到的引擎主要就是2个&#xff1a;Innodb和MyIASM。 Innodb&#xff1a;它提供了对数据库ACID事务的支持&#xff0c;并且还提供行级锁和外键的约束。它被设计的目的就是处理大数据容器的数据库系统&#xff0c;它本身…

一文搞定接口幂等性架构设计方案

幂等性介绍 现如今很多系统都会基于分布式或微服务思想完成对系统的架构设计。那么在这一个系统中&#xff0c;就会存在若干个微服务&#xff0c;而且服务间也会产生相互通信调用。那么既然产生了服务调用&#xff0c;就必然会存在服务调用延迟或失败的问题。当出现这种问题&a…

系列四、Nginx的常用命令和配置文件

一、常用命令 1.1、查看nginx的版本号 ./nginx -v 1.2、启动nginx cd /usr/local/nginx/sbin./nginx 1.3、停止nginx cd /usr/local/nginx/sbin./nginx -s stop 1.4、重新加载nginx 说明&#xff1a;该命令用于修改配置文件后&#xff0c;在不重启nginx的情况下使配置文…

ClickHouse的WITH-ALIAS是如何实现的

ClickHouse的WITH-ALIAS是如何实现的 WITH-ALIAS包含相似但不同的两个特性&#xff1a; WITH <表达式> as <别名>WITH <别名> as <子查询> WITH <表达式> as <别名> 特性 以下SQL展示了 WITH <表达式> as <别名> 特性的用…

FPGA通信—千兆网(UDP)软件设计

一、PHY引脚功能描述 引脚功能描述1CLK25 CLK125:内部PLL生成的125MHz参考时钟&#xff0c;如MAC未使用125MHe时钟&#xff0c;则此引脚应保持浮动&#xff0c; 2 4 63 GND 接地3REG OUT开关压器&#xff0c;1.05V输出 5 6 8 9 11 12 14 15 MDI[0] MDI[0]- MDI[1] MDI[1…

学习笔记-BNF、EBNF、ABNF语法格式描述规范

目标是确认一些c/cpp的语法细节&#xff0c;需要看cpp语法定义文件。 考虑从c的语法定义文件开始确认。 考虑实现一个简化的语言定义和编译器&#xff0c;为后续的实际需求做自定义扩展。 参考网页&#xff1a; https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_f…

高可用Kuberbetes部署Prometheus + Grafana

概述 阅读官方文档部署部署Prometheus Grafana GitHub - prometheus-operator/kube-prometheus at release-0.10 环境 步骤 下周官方github仓库 git clone https://github.com/prometheus-operator/kube-prometheus.git git checkout release-0.10 进入工作目录 cd kube…

【linux命令讲解大全】100. Linux常用文件传输命令详解

文章目录 cd概要主要用途参数选项返回值例子关于切换到上一个工作目录的说明关于 CDPATH关于 cdable_vars注意 从零学 python cd 切换用户当前工作目录。 概要 cd [-L|[-P [-e]]] [dir] 主要用途 切换工作目录至 dir。其中 dir 的表示法可以是绝对路径或相对路径。若参数 …

二、[mysql]之Explain讲解与实战

目录 一、了解Explain1.Explain介绍 二、Explain相关字段1.partitions2.filtered3.SHOW WARNINGS命令 三、Explain比较重要字段1.id2.select_type3.table4.type5.possible_keys6.key7.key_len8.ref9.rows10.Extra 四、索引优化实战&#xff08;遵循原则&#xff09;1.全值匹配2…

Linux 系统中查看和停止删除定时任务

文章目录 linux系统定时任务之crontab什么是crontabcrond 在 Linux 系统中查看当前配置的定时任务停止和删除定时任务的方法cron定时任务控制防火墙恢复 linux系统定时任务之crontab 什么是crontab 在Linux或类Unix系统中&#xff0c;通常使用crontab命令在指定的时间执行一个…

python关闭指定进程以excel为例

先说下环境&#xff1a; Excel版本&#xff1a; Python2.7.13和Python3.10.4并存。 2、打开两个excel工作簿 看进程是这样的&#xff1a; 3、用python编程kill进程 # -*- coding: utf-8 -*- import os proc_nameEXCEL.EXE if __name__ __main__:os.system(taskkill /im {} /…

【vue2第十六章】VueRouter 声明式导航(跳转传参)、路由重定向、页面未找到的提示页面404、vue路由模式设置

声明式导航(跳转传参) 在一些特定的需求中&#xff0c;跳转路径时我们是需要携带参数跳转的&#xff0c;比如有一个搜索框&#xff0c;点击搜索的按钮需要跳转到另外一个页面组件&#xff0c;此时需要把用户输入的input框的值也携带到那页面进行发送请求&#xff0c;请求数据。…

python 随机生成emoji表情

问答板块觉得比较有意思的问题 当时搜了些网上的发现基本都不能用&#xff0c;不知道是版本的问题还是咋的就开始自己研究 python随机生成emoji 问题的产生解决官网文档数据类型实现思路实现前提&#xff1a;具体实现&#xff1a; 其他常见用法插入 Emoji 表情&#xff1a;解析…

【ES6】Class中this指向

先上代码&#xff1a; 正常运行的代码&#xff1a; class Logger{printName(name kexuexiong){this.print(hello ${name});}print(text){console.log(text);} }const logger new Logger(); logger.printName("kexueixong xiong");输出&#xff1a; 单独调用函数p…

【Java基础】学习笔记5 - 包装类与集合介绍

目录 第四阶段包装类StringStringBufferArraysSystemCollectionArrayListVector 第四阶段 包装类 装箱拆箱以及手动自动 package chapter4;public class Pack {public static void main(String[] args) {// 自动装箱int a 100;Integer aa a;// 自动拆箱int b aa;// 手动装…

搭建自己的OCR服务,第二步:PaddleOCR环境安装

PaddleOCR环境安装&#xff0c;遇到了很多问题&#xff0c;根据系统不同问题也不同&#xff0c;不要盲目看别人的教程&#xff0c;有的教程也过时了&#xff0c;根据实际情况自己调整。 我这边目前是使用windows 10系统CPU python 3.7 搭建。 熟悉OCR的人应该知道&#xff0…

合宙Air724UG LuatOS-Air LVGL API控件-标签 (Label)

标签 (Label) 标签是 LVGL 用来显示文字的控件。 示例代码 label lvgl.label_create(lvgl.scr_act(), nil) lvgl.label_set_recolor(label, true) lvgl.label_set_text(label, "#0000ff Re-color# #ff00ff words# #ff0000 of\n# align the lines …

时间管理类书籍阅读笔记

背景 这段时间看了时间管理方面的书籍&#xff0c;大部分和早晨时间利用相关。之所以有了利用早晨时间的想法&#xff0c;是某天下班后&#xff0c;感觉很疲惫&#xff0c;什么都不想做&#xff0c;于是就打了一晚上游戏&#xff0c;然后第二天重复着这样的生活。 突然意识到…

基于Spring、SpringMVC、Mybatis的超市管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SSM的超市订单管理系统,java项目。 …