第三章:查找与排序(下)----------- 3.16堆的概念及堆排序思路

海量数据处理问题 分而治之 hash表 堆排序 一、分而治之/Hash映射 + Hash统计 + 堆/快速/归并排序 分而治之:通过hash将大文件分为小文件,大数据分为小数据等; hash统计:整合每个小文件,筛选重复数据,记录大小; (可用到map / hash_map / set / hash_set等) 归并:整合每个小文件的hash统计结果,得到最终结果。 寻找热门查询,300万个查询字符串中统计最热门的10个查询 阅读详情

堆的概念及堆排序思路:

二叉堆是完全二叉树,或者近似完全二叉树。

二叉堆满足两个特性:

---1、父节点的键值总是大于或等于(小于或等于)任何一个节点的键值;

---2、每个节点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

任何节点的值都大于其子节点的值------大顶堆

任何节点的值都小于其子节点的值------小顶堆

 堆排序:

1、堆化,反向调整使得每个子树都是大顶或者小顶堆;

2、按序输出元素:把堆顶和堆末元素对调,然后调整堆顶元素。

伪代码: 

MakeMinHeap(A){
	n=A.length;
	for i from n/2-1 down to 0{
		MinHeapFixDown(A,i);
	}
}


/*
①、先看有没有左右孩子; 
②、找到左右孩子中较小的那个; 
③、调整(交换或者不交换); 
④、递归地向下调整。 
*/

MinHeapFixDown(A,i,n){
	//找到左右孩子
	left=2*i+1;
	right=2*i+2; 
	//左孩子已经越界,i就是叶子节点	
	if(left>=n){
		return;
	}
	min=left;
	if(right>=n){
		min=left;
	}
	else{
		if(A[right]<A[left]){
			min=right;
		}
	}
	//min指向了左右孩子中较小的那个 
	
	//如果A[i] 比两个孩子都要小,不用调整
	if(A[i]<=A[min]){
		return;
	} 
	
	//否则,找到两个孩子中较小的,和i交换
	temp=A[i];
	A[i]=A[min];
	A[min]=temp;
	
	//小孩子那个位置的值发生了变化,i变更为小孩子那个位置,递调整
	MinHeapFixDown(A,min,n);
}

 

//sort函数:
sort(A){
	//先对A进行堆化
	MakeMinHeap(A);
	for(int x=n-1;x>=0;x--)
		//把堆顶,0号元素和最后一个元素对调
		swap(A,0,x);
  		//缩小堆的范围,对堆顶元素进行向下调整 
  		MinHeapFixDown(A,0,x-1);
} 

代码:

#include<iostream>
using namespace std;
/**
*思路:首先要知道大顶堆和小顶堆,数组就是一个堆,每个i节点的左右孩子是2i+1和2i+2 
*      有了堆,将其堆化:从n/2-1个元素开始向下修复,将每个节点修复为小(大)顶堆 
*      修复完成后,数组具有小(大)顶堆的性质 
*      按序输出:小顶堆可以对数组逆序排列,每次交换堆顶和末尾元素,对栈顶进行向下修复 
*
*时间复杂度:堆化:一半的元素修复,修复是单分支的,所以整体堆化为nlgn。(PS:常数因子较大)
*排序:n个元素都要取出,因此调整为n次,每次调整修复同上是lgn的,整体为nlgn 
*空间复杂度:不需要开辟辅助空间 
*原址排序 
* 稳定性:不稳定 
*/
void MinHeapFixDown(int A[],int i,int n); 

void makeMinHeap(int A[],int length){
	int n=length;
	for(int i=n/2-1;i>=0;i--){
		MinHeapFixDown(A,i,n);
	}
} 

//向下调整函数 
void MinHeapFixDown(int A[],int i,int n){
	//找到左右孩子
	int left=2*i+1;
	int right=2*i+2;
	//左孩子已经越界,i就是叶子节点
	if(left>=n){
		return;
	} 
	 int min=left;
	 if(right>=n){
	 	min=left;
	 }
	 else{
	 	if(A[right]<A[left]){
	 		min=right;
	 	}
	 }
	 //min指向了左右孩子中较小的那个
	 
	 //如果A[i]比两个孩子都要小,不用调整
	 if(A[i]<A[min]){
	 	return;
	 } 
	 //否则,找到两个孩子中较小的,和i交换
	 int temp=A[i];
	 A[i]=A[min];
	 A[min]=temp;
	 
	 //小孩子那个位置的值发生了变化,i变更为小孩子的那个位置,递归调整
	 MinHeapFixDown(A,min,n);	 
}

//排序函数
void sort(int A[],int length){
	//先对A进行堆化
	makeMinHeap(A,length);
	for(int x=length-1;x>=0;x--){
		//把堆顶,0号元素和最后一个元素对调		
		swap(A[0],A[x]);
		//缩小堆的范围,对堆顶元素进行向下调整 
		MinHeapFixDown(A,0,x);
	}
} 

int main(){
	int arr[]={6,2,5,8,2,1,9,5,6};
	int len= 9;
	
	sort(arr,len);
	for(int i=0;i<len;i++){
		cout<<arr[i]<<" ";
	}
	return 0;
} 

结果:

uniapp - H5网页uni.getLocation报错getLocation:fail Geolocation permission denied.Get ipLocation failed. uni.getLocation getLocation:fail Geolocation permission denied.Get ipLocation failed.,uni.getLocation定位失败,uni-app getLocation()无法获取定位,一直fail()uniapp移动端h5网页,uniApp微信内置浏览器定位失败,如何解决这个问题,uniapp h5 uni.getLocation获取位置失败怎么办,UNI-APP获取当前位置,uni.getLocation定位失败,unia 阅读详情

相关推荐

TensorRT(C++)部署 Pytorch模型

众所周知,python训练pytorch模型得到.pt模型。但在实际项目应用中,特别是嵌入式端部署时,受限于语言、硬件算力等因素,往往需要优化部署,而tensorRT是最常用的一种方式。本文以yolov5的部署为例,说明模型部署在x86架构上的电脑端的流程。(部署在Arm架构的嵌入式端的流程类似)。

女神sha手的博客 5409

堆和栈的概念和区别 python_排序(6):堆排序

摘要堆排序是利用堆的性质进行的一种选择排序。一、前言堆排序是一种选择排序。选择排序:每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。二、算法思想堆排序是利用堆的性质进行的一种选择排序。动态效果示意图:堆是一棵顺序存储的完全二叉树。其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆。其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆...

weixin_39963341的博客 353

ROS 入门教程:小乌龟仿真器和基础操作

小乌龟仿真器和ros基础操作

zlflll的博客 4127

Java基础之一维数组,栈内存,堆内存和数组排序和查找(冒泡排序,选择排序,折半查找)

一.一维数组 一维数组:保存一组相同数据类型的元素 1.声明方式: 数据类型[] 数组名 = 初值;数据类型表示的是数组中保存的元素的数据类型 注意:数组的长度一但确定就不能改变 2.创建数组的方法: //方法一:数据类型[] 数组名 = new 数据类型[数组长度]; //方法二:数据类型[] 数组名 = new 数据类型[] {1,2,3,4,5}; //方法三:数据类型[] 数组...

KongLingLei_08225的博客 481

Rust练手:从零手撸RISC-V架构虚拟机(一)(附完整代码)

使用Rust实现一个简单的RISC-V架构的CPU雏形,支持add,sub,addi三个指令。

qq_45983373的博客 2574

UCIe物理层 —— 逻辑协议 (2)

本章开始主要介绍UCIe协议第四章,物理层逻辑定义和规范。如其他的通信协议一样,接口的物理层包含两个部分,逻辑子层和电气子层。其中逻辑层主要负责:1.定义接口信号和时序2. 定义发送端如何将上层数据分发到各个物理通道以及接收端如何把从各个通道收到的数据恢复成byte stream(Flit)。3. Broken Lane的repair和remap。4. 链路初始化,训练(training)和电源状态管理/切换。5. 扰码Scrambling和training sequence的产生。

m0_47581558的博客 1481

堆排序算法的Java实现与分析

1、堆排序算法的简单介绍 顾名思义哈,堆排序算法就是使用堆这种数据结构设计的一种排序算法,关于堆排序算法网上能找到太多的的资料讲解,但我是为了自己学习自己理解来写的博客,所以我呢只在我的博客中记录关键的一些知识点。 堆排序算法的关键知识点: 时间复杂度:在最好、最坏、平均情况下的时间复杂度都是O(nlogn); 稳定性:是一种不稳定的排序算法 堆分为大根堆和小根堆,相应的堆排序算法分...

weixin_30335353的博客 186

stm32控制舵机_使用URT-1控制飞特舵机上手教程(SM40BL舵机为例)

使用URT-1控制飞特舵机上手教程(SM40BL舵机为例):1,参阅URT-1使用说明.pdf2, 材料清单:① URT-1驱动板② 连接驱动板与电脑的MINI USB 连接线③ 给舵机供电的电源④ 舵机与舵机连接线⑤ 杜邦线(可选)3,将URT-1驱动板与电脑连接4,安装驱动,参阅文件CH340驱动,检查设备管理器串口号。5,舵机连接URT-1驱动板,驱动板接电源,参考下图:6,打开FD软件进行...

weixin_39564510的博客 3432

Java堆排序算法详解与面试应用

堆排序是一种基于完全二叉树结构的经典排序算法,通过构建大顶堆或小顶堆实现数据排序。其核心原理是利用堆化(Heapify)操作维护堆性质,时间复杂度稳定在O(nlogn)。在Java中,PriorityQueue优先队列底层就是堆实现,常用于解决Top K问题等实际场景。作为面试高频考点,堆排序融合了数据结构、算法思想和工程实践三大维度,特别适合考察候选人的编码能力和算法思维。掌握堆排序的Java实现、时间复杂度分析以及变种问题解法,对于准备技术面试和提升工程能力都大有裨益。

weixin_30268071的博客 434

手推反向传播+numpy实现

反向传播的重要性不必多说,手推也是必备基础,大厂面试要求用numpy实现一下BP也是经常的事。下面以一个简单的两层网络为例(简单到连bias都没有的那种),真·手推反向传播+numpy实现。 说明: input:输入 net_h:隐层 S(x):sigmoid简写 SD(x):sigmoid导数的简写 out_h:隐层经过sigmoid激活的输出 net_o:输出层 out_o:经过经过sigmoid激活的输出层,也就是最后的输出 target(简写t1、t2):Ground...

xian0710830114的专栏 1238

杰理SDK入门教程(一):编译环境的安装和程序下载

本文档提供了杰理SDK在Windows系统下的开发环境配置与代码编译指南。主要内容包括:1) 开发环境安装步骤,需下载Code::Blocks和杰理工具链;2) 编译过程中常见问题的解决方案,如安全警告提示和链接文件缺失问题;3) 代码编译流程说明,包括打开工程、连接开发板、执行编译等步骤。文档特别强调了强制升级模式的操作方法,并指出需避免点击运行/调试按钮。最后提示了杀毒软件可能误报工具链的注意事项。

qq_42014563的博客 2744

一文讲清楚堆

堆是一种满足特定条件的完全二叉树分为两种:大根堆:所有父节点都大于等于子节点小根堆:所有父节点都小于等于子节点大根堆的示例:对应的数组表示: 在这个大根堆中:小根堆的示例:对应的数组表示: 在这个小根堆中:完全二叉树的特性使得可以用数组来存储,对于索引i的节点:定义一个堆: 二、堆的常见操作 方法名 描述 时间复杂度 HeapPush(Hp* ph, HpDataType val) 堆顶插入元素 O(logN)

Vect的博客 1253

全覆盖路径规划开源项目Clean-robot-turtlebot3原理及流程概括总结

本系列文章主要介绍全覆盖路径规划开源项目Clean-robot-turtlebot3的相关内容,包含如下四篇文章,分别介绍了开源项目Clean-robot-turtlebot3流程的概括总结、ROS坐标系常用坐标及其变换、Clean-robot-turtlebot3关键函数解析等内容。

慕羽★的博客 6108

堆排序算法深度解析:从原理到实战应用与性能优化

排序算法是计算机科学的基础,它通过特定的比较和交换逻辑将数据元素按序排列,其核心价值在于提升数据检索与处理的效率。从原理上看,高效的排序算法往往依赖于巧妙的数据结构设计,例如利用分治策略或特殊树形结构来降低时间复杂度。堆排序正是基于‘二叉堆’这一完全二叉树结构实现的原地排序算法,其技术价值在于能够稳定地提供O(n log n)的时间复杂度,且空间复杂度仅为O(1),特别适用于内存敏感或需要保证最坏情况性能的场景。在应用层面,堆排序及其背后的堆数据结构是解决‘Top K问题’和实现‘优先队列’的关键,广泛应用

weixin_30756499的博客 502

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

基于比较的常见的排序

文章目录一、基数排序二、直接插入排序1.直接插入排序思路与代码2.直接插入排序特点、时间复杂度、空间复杂度、稳定性分析3.折半插入排序(了解)三、希尔排序1.希尔排序思路与代码2.希尔排序特点、时间复杂度、空间复杂度、稳定性分析四、选择排序1.选择排序思路与代码2.选择排序特点、时间复杂度、空间复杂度、稳定性分析五、冒泡排序1.冒泡排序思路与代码2.冒泡排序特点、时间复杂度、空间复杂度、稳定性分析六、堆排序1.堆排序的思路与代码2.堆排序特点、时间复杂度、空间复杂度、稳定性分析七、快速排序1.快速排序的思路

ZJRUIII的博客 2482

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

leetcode 378(二维数组的二分法与堆排序)

解题思路: 利用二分法: 对此题用二分法,和一维数组的二分法不同,何况一维数组是一个已经排好序的数组,在磁体中,要求的是第k小元素,所以该值拥有k个小于等于他的元素。 假设有以下二维数组: [[1, 5, 9], [3, 10, 15], [6, 16, 20]] 要找出第6大的值,即k = 6 首先将lo指向整个二维数组最小的值a[0][0],hi指向最大的值a[2][2] 求出lo 和 ...

wqylry的博客 1364

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

堆排序及其c语言实现

堆的性质:堆是一棵完全二叉树,它有最大堆和最小堆之分,这里只分析最大堆!(最小堆与最大堆类似) 就是所有的子节点都小于根节点的完全二叉树 堆的几种操作(数组实现): 其中 len 表示 数组长度,headsize表示堆的长度 其中堆的左节点编号 int LEFT(int i ) { return i*2; } 堆的右节点编号: int RIGHT(int i ) ...

weixin_30793643的博客 134

堆排序(python实现)

 堆排序是利用最大最或最小堆,废话不多说: 先给出几个概念: 二叉树:二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树” 完全二叉树:除最后一层外,每一层上的节点数均达到最大值;在最后一层上只缺少右边的若干结点。 满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点。 堆:堆是一种数据结构,类似树根结构,如...

weixin_30239339的博客 163

堆排序及拓展

set 请写出堆排序的代码。 输入n个整数,找出其中最小的k个数。 1、思路:   堆排序分为建堆(insertion)和取根数据(delete root)。每一步都涉及到堆调整,堆调整算法的时间复杂度为O(logn)。 HeapSort 1 #include <stdio.h> 2 3 #define heap_parent(npos) ((int...

weixin_30305735的博客 127

java的堆_java数据结构----堆

1.堆:堆是一种树,由它实现的优先级队列的插入和删除的时间复杂度都是O(logn),用堆实现的优先级队列虽然和数组实现相比较删除慢了些,但插入的时间快的多了。当速度很重要且有很多插入操作时,可以选择堆来实现优先级队列。2.java的堆和数据结构堆:java的堆是程序员用new能得到的计算机内存的可用部分。而数据结构的堆是一种特殊的二叉树。3.堆是具有如下特点的二叉树:3.1.它是完全二叉树,也就是...

weixin_31880681的博客 342

算法三、排序与查找

快速排序、双路快排、三路快排、基数排序、桶排序、计数排序、所有排序测试速度含数据、二分查找、插值查找

Ningmengyouzhi的博客 554

算法--堆排序

1、基本概念堆是二叉树的一种,堆中每个节点都大于其左右子节点称为大顶堆,如果每个节点都小于其左右节点的值则为小顶堆。使用完全二叉树实现的堆有如下性质 1.2 思路 将待排序的序列构造成大顶堆,此时最大值就是堆的根元素。将它与末尾元素交换,然后将剩余的n-1个元素重新构造成大顶堆,然后再与n-1个元素交换。 2、实现:public static void main(String[] ar

with_dream的博客 255

好理解的堆排序

对于堆排序,其实就是一个路径上的冒泡的过程,所以可以用这个思想去写代码, 思路:每次父节点都和他的左子树和右子树比较,三者中最大的那个与父节点交换位置,这样递归之后根节点存放的就是该次遍历最大的值,之后将根节点与最后的节点交换,在进行查找(0~(lenth-1))中的最大值与倒数第二个交换位置就OK了。这样自己比较好理解。 1 #include <iostream> 2 ...

weixin_30413739的博客 88

广州大学数据结构实验四

广州大学数据结构实验四 1、各种排序算法的实现2、各种查找算法

a2637024245的博客 1391

数据结构 - 几种常见的排序方法

排序: 分类: 稳定和不稳定的排序:假设一组排序中有两个相同的数字,排序前后排序后两个数字的先后顺序不变;不稳定的排序则有可能发生改变。 内排序和外排序:内排序指的是在内存中排序,外排序则涉及到外部的存储空间 排序方法: 排序方法又分为很多种有:插入类排序,交换类排序,选择类排序,归并排序,基数排序 插入排序又分为:直接插入排序,折半插入排序,2-路插入排序,表插入排序和希尔排序等。 直接插入排序: 简介:直接插入排序是最简单的一种算法 思路:添加新的记录时,使用顺序查找的方式..

绿龙术士的专栏 1994
上一篇: 第三章:查找与排序(下)----------- 3.15基础学习_树、二叉树、堆排序
下一篇: 第三章:查找与排序(下)----------- 3.19 计数排序
Estrellas_
博客等级 码龄9年 273粉丝 233原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值