【数据结构】二叉树--堆排序

目录

一 降序(建小堆)

二 升序 (建大堆)

​三 优化(以升序为例)

四 TOP-K问题


一 降序(建小堆)

void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}//降序 建小堆
void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] < a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}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 = parent * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)
{int end = n - 1;int i = 0;//建堆for (i = 1; i < n; i++){AdjustUp(a, i);}while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}int main()
{int a[] = { 2, 3, 5, 7, 4, 6, 8 };HeapSort(a, sizeof(a) / sizeof(int));return 0;
}

二 升序 (建大堆)

//升序 建大堆
void AdjustUp(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}
}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 = parent * 2 + 1;}else{break;}}
}void HeapSort(int* a, int n)
{int end = n - 1;int i = 0;//建堆for (i = 1; i < n; i++){AdjustUp(a, i);}while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}int main()
{int a[] = { 2, 3, 5, 7, 4, 6, 8 };HeapSort(a, sizeof(a) / sizeof(int));return 0;
}

三 优化(以升序为例)

可以用向下建堆的方法

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 = parent * 2 + 1;}else{break;}}
}//void HeapSort(int* a, int n)
//{
//	int end = n - 1;
//	int i = 0;
//	//建堆
//	for (i = 0; i < n; i++)
//	{
//		AdjustUp(a, i);
//	}
//
//	while (end > 0)
//	{
//		Swap(&a[0], &a[end]);
//		AdjustDown(a, end, 0);
//		end--;
//	}
//}void HeapSort(int* a, int n)
{int end = n - 1;int i = 0;//建大堆for (i = (n-1-1) / 2; i >= 0; i--){AdjustDown(a, n, i);}while (end > 0){Swap(&a[0], &a[end]);AdjustDown(a, end, 0);end--;}
}
int main()
{int a[] = { 2, 3, 5, 7, 4, 6, 8, 65, 100, 70, 32, 50, 60};HeapSort(a, sizeof(a) / sizeof(int));return 0;
}

 

这样建堆的方式对时间复杂度有什么优化吗?

 

四 TOP-K问题

TOP - K问题:即求数据结合中前K个最大的元素或者最小的元素,一般情况下数据量都比较大。

比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。

对于Top - K问题,能想到的最简单直接的方式就是排序,但是:如果数据量非常大,排序就不太可取了(可能数据都不能一下子全部加载到内存中)。最佳的方式就是用堆来解决,基本思路如下:1. 用数据集合中前K个元素来建堆

    前k个最大的元素,则建小堆

    前k个最小的元素,则建大堆

2. 用剩余的N - K个元素依次与堆顶元素来比较,不满足则替换堆顶元素

将剩余N-K个元素依次与堆顶元素比完之后,堆中剩余的K个元素就是所求的前K个最小或者最大的元素。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>typedef int HPDataType;void Swap(HPDataType* p1, HPDataType* p2)
{HPDataType tmp = *p1;*p1 = *p2;*p2 = tmp;
}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 = parent * 2 + 1;}else{break;}}
}void PrintTopK(const char* filename, int k)
{//1 建堆--用a中前K个元素建堆(小堆)FILE* fout = fopen(filename, "r");if (fout == NULL){perror("fopen fail");return;}int* minheap = (int*)malloc(sizeof(int) * k);if (minheap == NULL){perror("malloc fail");return;}for (int i = 0; i < k; i++){fscanf(fout, "%d", &minheap[i]);}//前K个建小堆for (int i = (k-2) / 2; i >= 0; i--){AdjustDown(minheap, k, i);}//2 将剩余n-k元素与堆顶元素比较, 满足就交换int x = 0;while (fscanf(fout, "%d", &x) != EOF){if (x > minheap[0]){//替换进堆minheap[0] = x;AdjustDown(minheap, k, 0);}}for (int i = 0; i < k; i++){printf("%d ", minheap[i]);}printf("\n");fclose(fout);}void CreateDate()
{//造数据int n = 100000;srand(time(0));const char* file = "data.txt";FILE* fin = fopen(file, "w");if (fin == NULL){perror("fopen error");return;}for (int i = 0; i < n; i++){int x = (rand() + i) % n;fprintf(fin, "%d\n", x);}fclose(fin);
}int main()
{CreateDate();PrintTopK("data.txt", 5);return 0;
}

 

本节对前面的二叉树基础很高, 没有理解的, 可以翻看我之前对二叉树顺序结构及其实现的章节.

继续加油! 

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

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

相关文章

Ubuntu 22.04.3 LTS单机私有化部署sealos

推荐使用奇数台 Master 节点和若干 Node 节点操作系统 :Ubuntu 22.04 LTS内核版本 :5.4 及以上配置推荐 :CPU 4 核 , 内存 8GB, 存储空间 100GB 以上最小配置 :CPU 2 核 , 内存 4GB, 存储空间 60GB 这里采用的Ubuntu 22.04.3 LTS 版本&#xff0c;Ubuntu 20.04.4 LTS这个版本…

Eclipse插件安装版本不兼容问题解决方案——Papyrus插件为例

项目场景: Eclipse Papyrus安装后,没有新建Papyrus工程选项,也没有新建Papyrus Model的选项。 打开Papyrus Model会报错 问题描述 同样的,安装其他插件也是。可能某个插件之前安装是好用的,结果Eclipse的版本更新了,就再也安装不好用了 原因分析: 根本原因是因为包之…

Xcode 15下,包含个推的项目运行时崩溃的处理办法

升级到Xcode15后&#xff0c;部分包含个推的项目在iOS17以下的系统版本运行时&#xff0c;会出现崩溃&#xff0c;由于崩溃在个推Framework内部&#xff0c;无法定位到具体代码&#xff0c;经过和个推官方沟通&#xff0c;确认问题是项目支持的最低版本问题。 需要将项目的最低…

十七、【渐变工具组】

文章目录 渐变工具油漆桶工具 渐变工具 渐变样式有5种&#xff0c;分别是线性渐变&#xff0c;径向渐变&#xff0c;角度渐变&#xff0c;对称渐变&#xff0c;菱形渐变 另外渐变工具的颜色可以进行编辑&#xff0c;需要先打开渐变编辑工具&#xff1a; 如何使用渐变编辑工…

与HTTP相关的各种概念

网络世界 网络世界中最重要的一个名词就是互联网&#xff08;Internet&#xff09;,它以TCP/IP协议族为基础&#xff0c;构建成了一望无际的信息传输网络。而我们通常所说的“上网”&#xff0c;主要就是访问互联网的一个子集——万维网&#xff08;World Wide Web&#xff09…

如何使用CSS和JavaScript实施暗模式?

近年来&#xff0c;暗模式作为用户界面选项备受追捧。它提供了更暗的背景和更亮的文本&#xff0c;不仅可以减轻眼睛疲劳&#xff0c;还可以节省电池续航时间&#xff0c;尤其是在OLED屏幕上。 不妨了解如何结合使用CSS和JavaScript为网站和Web应用程序添加暗模式选项。 了解暗…

JWT的原理及实际应用

前言&#xff1a; 定义&#xff1a;JSON Web Token&#xff08;缩写 JWT&#xff09;是目前最流行的跨域认证解决方案 JWT官网 由于HTTP协议是无状态的&#xff0c;这意味着如果我们想判定一个接口是否被认证后访问&#xff0c;就需要借助cookie或者session会话机制进行判定&…

保姆级手把手记录Android studio BottomNavigationView +FrameLayout暴力切换Fragment

开发环境&#xff1a; 效果图&#xff1a; 《《《代码在底部》》》 1&#xff0c;新建项目 2&#xff0c;新建若干Fragment&#xff0c;内容一样&#xff0c;改一下显示出来的Text&#xff0c;名字分别为test1Fragment,test2Fragment,test3Fragment,默认TextView的Text属性分别…

交通 | python网络爬虫:“多线程并行 + 多线程异步协程

推文作者&#xff1a;Amiee 编者按&#xff1a; 常规爬虫都是爬完一个网页接着爬下一个网页&#xff0c;不适应数据量大的网页&#xff0c;本文介绍了多线程处理同时爬取多个网页的内容&#xff0c;提升爬虫效率。 1.引言​ 一般而言&#xff0c;常规爬虫都是爬完一个网页接着…

代码随想录算法训练营第五十二天 | 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

123.买卖股票的最佳时机III 视频讲解&#xff1a;动态规划&#xff0c;股票至多买卖两次&#xff0c;怎么求&#xff1f; | LeetCode&#xff1a;123.买卖股票最佳时机III_哔哩哔哩_bilibili 代码随想录 &#xff08;1&#xff09;代码 188.买卖股票的最佳时机IV 视频讲解&a…

文字雨特效

效果展示 CSS 知识点 简易实现云朵技巧text-shadow 属性的灵活运用filter 属性实现元素自动变色 实现页面布局 <div class"container"><div class"cloud"><h2>Data Clouds Rain</h2></div> </div>实现云朵 实现云…

从基础到卷积神经网络(第12天)

1. PyTorch 神经网络基础 1.1 模型构造 1. 块和层 首先&#xff0c;回顾一下多层感知机 import torch from torch import nn from torch.nn import functional as Fnet nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X torch.rand(2, 20) # 生成随机…

<图像处理> Fast角点检测

Fast角点检测 基本原理是使用圆周长为N个像素的圆来判定其圆心像素P是否为角点&#xff0c;如下图所示为圆周长为16个像素的圆&#xff08;半径为3&#xff09;&#xff1b;OpenCV还提供圆周长为12和8个像素的圆来检测角点。 相对中心像素的位置信息 //圆周长为16 static c…

Lumen/Laravel - 事件机制原理与工作流程 - 探究

1.应用场景 主要用于学习与探究Lumen/Laravel的事件机制原理与工作流程。 2.学习/操作 1.文档阅读 chatgpt & 其他资料 2.整理输出 2.1 是什么 TBD 2.2 为什么需要「应用场景」 TBD 2.3 什么时候出现「历史发展」 TBD 2.4 怎么实践 TBD 截图 后续补充 ... 3.问题…

深度学习基础知识 Dataset 与 DataLoade的用法解析

深度学习基础知识 Dataset 与 DataLoade的用法解析 1、Dataset2、DataLoader参数设置&#xff1a;1、pin_memory2、num_workers3、collate_fn分类任务目标检测任务 1、Dataset 代码&#xff1a; import torch from torch.utils import dataclass MyDataset(torch.utils.data.D…

语言模型编码中/英文句子格式详解

文章目录 前言一、Bert的vocab.txt内容查看二、BERT模型转换方法(vocab.txt)三、vocab内容与模型转换对比四、中文编码总结 前言 最近一直在学习多模态大模型相关内容&#xff0c;特别是图像CV与语言LLM模型融合方法&#xff0c;如llama-1.5、blip、meta-transformer、glm等大…

Elasticsearch 和 Arduino:一起变得更好!

作者&#xff1a;Enrico Zimuel 使用 Arduino IoT 设备与 Elasticsearch 和 Elastic Cloud 进行通信的简单方法 在 Elastic&#xff0c;我们不断寻找简化搜索体验的新方法&#xff0c;并开始关注物联网世界。 来自物联网的数据收集可能非常具有挑战性&#xff0c;尤其是当我们…

《Unity Shader入门精要》笔记06

基础纹理 单张纹理纹理的属性Alpha SourceWrap ModeFilter Mode 凹凸映射高度纹理法线纹理实践在切线空间下计算在世界空间下计算 Unity中的法线纹理类型Create from Grayscale 渐变纹理遮罩纹理其他遮罩处理 单张纹理 我们通常会使用一张纹理来代替物体的漫反射颜色 Shader …

K8s Kubernetes Namespave Pod Label Deployment Service 实战

本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 Namespace Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 默认情况下&#xff0c;kubernetes集群中…

MySQL之双主双从读写分离

一个主机 Master1 用于处理所有写请求&#xff0c;它的从机 Slave1 和另一台主机 Master2 还有它的从 机 Slave2 负责所有读请求。当 Master1 主机宕机后&#xff0c; Master2 主机负责写请求&#xff0c; Master1 、 Master2 互为备机。架构图如下 : 准备 我们…