二叉树--堆(下卷)

二叉树–堆(下卷)

如果有还没看过上卷的,可以看这篇,链接如下:
http://t.csdnimg.cn/HYhax

向上调整算法

堆的插⼊

将新数据插⼊到数组的尾上,再进⾏向上调整算法,直到满⾜堆。

💡 向上调整算法

• 先将元素插⼊到堆的末尾,即最后⼀个孩⼦之后

• 插⼊之后如果堆的性质遭到破坏,将新插⼊结点顺着其双双亲往上调整到合适位置即可

在这里插入图片描述

代码如下:

//交换两个元素
void Swap(int* x, int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
//堆的向上调整算法
void AdjustUp(HPDataType* arr, int child)
{int parent = (child - 1) / 2;while (child > 0)//此时已经在头结点的位置,不是在根节点,不用等于0{if (arr[child] < arr[parent]){Swap( &arr[parent],&arr[child]);child = parent;parent = (child - 1) / 2;}else{break;}}
}

计算向上调整算法建堆时间复杂度

因为堆是完全⼆叉树,⽽满⼆叉树也是完全⼆叉树,此处为了简化使⽤满⼆叉树来证明(时间复杂度本 来看的就是近似值,多⼏个结点不影响最终结果)

在这里插入图片描述

分析:

第1层, 2 0 个结点,需要向上移动0层

第2层, 2 1 个结点,需要向上移动1层

第3层, 2 2 个结点,需要向上移动2层

第4层, 2 3 个结点,需要向上移动3层

第h层, 2 h−1 个结点,需要向上移动h-1层

则需要移动结点总的移动步数为:每层结点个数 * 向上调整次数(第⼀层调整次数为0)

在这里插入图片描述

由此可得:

💡 向上调整算法建堆时间复杂度为: O(n ∗ log n)

节点数量少的调整次数少;节点数量多的调整次数多

向下调整算法

堆的删除

删除堆是删除堆顶的数据,将堆顶的数据根最后⼀个数据⼀换,然后删除数组最后⼀个数据,再进⾏ 向下调整算法。

在这里插入图片描述

向下调整算法有⼀个前提:左右⼦树必须是⼀个堆,才能调整。

💡 向下调整算法

• 将堆顶元素与堆中最后⼀个元素进⾏交换

• 删除堆中最后⼀个元素

• 将堆顶元素向下调整到满⾜堆特性为⽌

在这里插入图片描述

代码如下:

//堆的向下调整
void AdjustDown(HPDataType* arr, int parent, int n)
{int child = 2 * parent + 1;//左孩子while (child<n){if (child + 1 && arr[child] > arr[child + 1]){child++;//比较孩子大小}if (arr[parent] > arr[child]){Swap( &arr[child],&arr[parent]);}else{break;}}
}

在这里插入图片描述

分析:

第1层, 2 0 个结点,需要向下移动h-1层

第2层, 2 1个结点,需要向下移动h-2层

第3层, 2 2 个结点,需要向下移动h-3层

第4层, 2 3 个结点,需要向下移动h-4层

第h-1层, 2 h−2 个结点,需要向下移动1层

则需要移动结点总的移动步数为:每层结点个数 * 向下调整次数

在这里插入图片描述

💡 向下调整算法建堆时间复杂度为: O(n)

节点数量少的调整次数多;节点数量多的调整次数少

堆的应⽤

堆排序

版本⼀:基于已有数组建堆、取堆顶元素完成排序版本

// 1、需要堆的数据结构
// 2、空间复杂度 O(N)
void HeapSort(int* a, int n)
{
HP hp;
for(int i = 0; i < n; i++)
{
HPPush(&hp,a[i]);
}
int i = 0;
while (!HPEmpty(&hp))
{
a[i++] = HPTop(&hp);
HPPop(&hp);
}
HPDestroy(&hp);
}

该版本有⼀个前提,必须提供有现成的数据结构堆

版本⼆:数组建堆,⾸尾交换,交换后的堆尾数据从堆中删掉,将堆顶数据向下调整选出次⼤的数据

void HeapSort(int* arr, int n)
{//建堆//升序--大堆//降序--小堆//向上调整算法//for (int i = 0; i < n; i++)//{//	AdjustUp(arr, i);//}// 堆的向下调整算法for (int i=(n - 1 - 1) / 2; i >= 0; i--)//从最后一个节点的父节点开始调整{AdjustDown(arr, i, n);}//循环数据,每次减少一个进行对比int end = 0;while (end > 0){Swap(&arr[0], &arr[end]);AdjustDown(arr,0 ,end);end--;}
}

堆排序时间复杂度计算
在这里插入图片描述

分析:

第1层,20 个结点,交换到根结点后,需要向下 移动0层

第2层, 21个结点,交换到根结点后,需要向下 移动1层

第3层,22 个结点,交换到根结点后,需要向下 移动2层

第4层, 23个结点,交换到根结点后,需要向下 移动3层

第h层,2 h-1个结点,交换到根结点后,需要向 下移动h-1层

通过分析发现,堆排序第⼆个循环中的向下调整与建堆中的向上调整算法时间复杂度计算⼀致,此处 不再赘述。因此,堆排序的时间复杂度为 O(n + n ∗ log n) ,即 O(n log n)

💡 堆排序时间复杂度为: O(n log n)

TOP-K问题

思路如下:
在这里插入图片描述

TOP-K问题:即求数据结合中前K个最⼤的元素或者最⼩的元素,⼀般情况下数据量都⽐较⼤。

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

对于Top-K问题,能想到的最简单直接的⽅式就是排序,但是:如果数据量⾮常⼤,排序就不太可取了 (可能数据都不能⼀下⼦全部加载到内存中)。最佳的⽅式就是⽤堆来解决,基本思路如下:

1)⽤数据集合中前K个元素来建堆

前k个最⼤的元素,则建⼩堆

前k个最⼩的元素,则建⼤堆

2)⽤剩余的N-K个元素依次与堆顶元素来⽐较,不满⾜则替换堆顶元素

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

代码如下:

void CreateNDate()
{
// 造数据
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) % 1000000;
fprintf(fin, "%d\n", x);
}
fclose(fin);
}
void topk()
{
printf("请输⼊k:>");
int k = 0;
scanf("%d", &k);
const char* file = "data.txt";
FILE* fout = fopen(file, "r");
if (fout == NULL)
{
perror("fopen error");
return;
}
int val = 0;
int* minheap = (int*)malloc(sizeof(int) * k);
if (minheap == NULL)
{
perror("malloc error");
return;
}
for (int i = 0; i < k; i++)
{
fscanf(fout, "%d", &minheap[i]);
}
// 建k个数据的⼩堆
for (int i = (k - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(minheap, k, i);
}
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]);
}
fclose(fout);
}

哈哈哈相信你在数据结构的学习道路上又进了一步,继续努力加油加油!!!未来的你一定会感谢现在努力的自己。你在三四月做的事情,在七八月会有回报!!
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

根据空域图信息构造飞机航线图以及飞行轨迹模拟matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 航路网络建模 4.2 航线图构建 4.3 飞行轨迹模拟的具体步骤 5.完整程序 1.程序功能描述 空域图是指航空领域中的一种图形表示方式&#xff0c;它涵盖了空中交通管理所需要的各种信息&a…

如何处理selenium Webdriver中的文本框?

文本框或字段在整个网页中广泛使用,本文将介绍如何在Java中使用Selenium Webdriver处理文本框。可以有各种文本字段,我们将尝试包括其中的大多数,并执行各种操作,如清除和输入文本。 我们将使用我们的Selenium游乐场网站- testkru,与各种文本框进行交互。您也可以使用同一…

藏文词典查单词,藏汉双语解释,推荐使用《藏语翻译通》App

《藏语翻译通》App推出了藏文词典、藏汉大词典、新术语等全新在线查单词功能。 藏汉互译 《藏语翻译通》App的核心功能之一是藏汉互译。用户只需输入中文或藏文&#xff0c;即可获得翻译结果。 藏文词典查单词 掌握一门语言&#xff0c;词汇是基础。《藏语翻译通》App内置藏…

诱骗IoT恶意软件跟踪CC服务器

工作背景 在分析 IoT 僵尸网络时&#xff0c;识别C&C 服务器至关重要。C&C 服务器的 IP 地址一直都是商业威胁情报的重要组成部分&#xff0c;由于 C&C 服务器通信协议日渐复杂并且活跃周期较短&#xff0c;时效性和准确性也非常重要。如果可以自动化识别 IoT 恶意…

力扣100题——128题

题目 ************************************************ 解&#xff08;哈希&#xff09; VS完整代码 #include<iostream> #include<vector> #include<unordered_set> #include<utility> #include<algorithm> using namespace std; int n, nu…

二叉树(2)

目录 2.5 二叉树的存储结构 3.二叉树的顺序结构及实现 3.1二叉树的顺序结构 3.2堆的概念以及结构 3.3堆的实现 3.4堆的代码实现 3.5堆的应用 书接上回&#xff0c;我们继续学习二叉树的知识 2.5 二叉树的存储结构 二叉树一般可以使用两种数据结构&#xff0c;一种顺序…

AI绘画模型之:UNet、Imagen 与 DeepFloyd IF

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

2024西安铁一中集训DAY27 ---- 模拟赛((bfs,dp) + 整体二分 + 线段树合并 + (扫描线 + 线段树))

文章目录 前言时间安排及成绩题解A. 倒水&#xff08;bfs dp&#xff09;B. 让他们连通&#xff08;整体二分 按秩合并并查集 / kruskal重构树&#xff09;C. 通信网络&#xff08;线段树合并 二分&#xff09;D. 3SUM&#xff08;扫描线 线段树&#xff09; 前言 T1没做出…

基于STM32瑞士军刀--【FreeRTOS开发】学习笔记(四)|| 同步 / 互斥 / 通信方法简介

本文概念部分粘贴自韦东山老师同步与互斥。 韦东山老师《FreeRTOS入门与工程实践(基于DshanMCU-103)》书籍获取 同步&互斥概念 一句话理解同步与互斥&#xff1a;我等你用完厕所&#xff0c;我再用厕所。 什么叫同步&#xff1f;就是&#xff1a;哎哎哎&#xff0c;我正在…

Linux中进程通信之信号

信号 信号通信&#xff0c;其实就是内核向用户空间进程发送信号&#xff0c;只有内核才能发信号&#xff0c;用户空间进程不能发送信号。 关于信号指令的查看&#xff1a;kill -l 例如我们之前使用的kill -9 pid用于杀死一个进程 使用一个死循环 成功发送kill -9指令&#x…

键盘输入数据的过程

当我们在键盘中按下按键的时候&#xff0c;键盘会向我们的 CPU 发送硬件中断&#xff08;也就是给 CPU 特定的针脚发送信号&#xff09;&#xff0c;该硬件中断有着自己的中断号&#xff0c;然后 CPU 内的寄存器就会记录下该中断号&#xff0c;然后会在操作系统中的中断向量表&…

DNTRo

文章目录 AbstractMethodExperimentConclusioninnovation link code Abstract 本文旨在解决计算机视觉领域中微小物体检测的问题。由于图像数据中微小物体所占像素比例很小&#xff0c;因此精确地检测这些物体仍然是一个巨大的挑战。特别是在地理科学和遥感领域&#xff0c;高…

18现代循环神经网络—seq2seq与束搜索

1.序列到序列学习(seq2seq) 上图展示的是 DNA 转录,它也是一种序列到序列的学习机器翻译 seq2seq 最早是用来做机器翻译的,给定一个源句子,自动翻译成目标语言给定一个源语言的句子,自动翻译成目标语言机器翻译中的输入序列和输出序列都是长度可变的seq2seq seq2seq 指的…

AI+生命科学方向第一课【Datawhale AI夏令营】

[我是大佬的搬运工] 01 赛题背景解析 http://competition.sais.com.cn/competitionDetail/532230/format 翻译一下&#xff1a; mRNA&#xff1a;疾病基因 siRNA&#xff1a;药物基因 RNAi&#xff1a;药物基因作用于疾病基因的机制 我们要完成的任务&#xff1a;预测某类…

力扣高频SQL 50题(基础版)第二十六题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十六题1667.修复表中的名字题目说明实现过程准备数据实现方式结果截图总结 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十六题 1667.修复表中的名字 题目说明 表&#xff1a; Users ----------------…

货拉拉论文入选亚太消费者研究会议及亚太营销国际学术会议

近日,亚太消费者研究会议(AP-ACR)召开。本次会议上,货拉拉和香港中文大学合作就论文《Why Showing Multiple Options Simultaneously Makes Customers Less Picky》(《为什么同步显示多个选项会使消费者变得更不挑剔》)进行主题报告。此前,本篇论文也曾在第二届亚太营销国际学术…

【Docomo】优质 4G

https://www.docomo.ne.jp/area/premium_4g/?icidCRP_AREA_technology_to_CRP_AREA_premium_4g 优质 4G 移动通信速度超过千兆字节LTE加速的主要基础技术256QAM44 MIMO&#xff08;麦莫&#xff09; 移动通信速度超过千兆字节 从 2020 年 3 月起将提供高达 1.7Gbps 的接收速度…

IoTDB 入门教程 实战篇⑤——Python示例(开源)

文章目录 一、前文二、新建Python项目三、安装依赖四、示例源码五、参考 一、前文 IoTDB入门教程——导读 本文详细阐述了如何通过一个Python项目成功连接到IoTDB时序数据库&#xff0c;进而展示了如何向该数据库高效地写入数据以及执行精确的数据查询操作。 此示例旨在为读者提…

云计算实训16——关于web,http协议,https协议,apache,nginx的学习与认知

一、web基本概念和常识 1.Web Web 服务是动态的、可交互的、跨平台的和图形化的为⽤户提供的⼀种在互联⽹上浏览信息的服务。 2.web服务器&#xff08;web server&#xff09; 也称HTTP服务器&#xff08;HTTP server&#xff09;&#xff0c;主要有 Nginx、Apache、Tomcat 等。…

程序员学长 | 快速学会一个算法,ANN

本文来源公众号“程序员学长”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;快速学会一个算法&#xff0c;ANN 今天给大家分享一个强大的算法模型&#xff0c;ANN。 人工神经网络 (ANN) 是一种深度学习方法&#xff0c;源自人类…