堆排序(建堆及向下调整)

2023-11-08 18:40
文章标签 堆排序 向下 调整 建堆

本文主要是介绍堆排序(建堆及向下调整),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,堆排序顾名思义,它的数据存储的像一个堆一样,那么想一下,像堆的数据类型都有什么?

树形结构!

在这里插入图片描述

所以,堆排序的存储就是通过一颗完全二叉树实现的,可以理解成满了,但没完全满 为什么这样说,原因很简单,它的n-1层组成的二叉树必须是满二叉树,但是叶子结点组成的第n层可以不满,但是有一个前提条件

假设根节点编号为1,两个子节点为2,3,那么2和3的子节点空余的顺序必须有序,就是说,4,5,6这三个叶子结点必须满足按顺序(也即是说,若6这个叶子结点存在,那么前面的说有叶子结点不可以空缺)

讲完了基本的概念,考虑他的分类和操作,它的分类• 大根堆每个结点的权值都比儿子的权值大• 小根堆• 每个结点的权值都比儿子的权值小

• 堆的性质—>大根堆的根结点一定权值最大,小根堆的根结点一定权值最

堆排序与普通的排序一样,有构建,插入,删除,维护的三种操作,但是,他是稳定的排序最坏的情况的复杂度为N(nlogn),若n的大小不是很大,可以视为N(n)

建堆:

•现在我们有一个数组a[1…n],如何把它初始化成一个堆?

从编号大的点,到编号小的点,依次进行“筛选”操作。就是实现一个简单的“sort”

所谓“筛选”指的是,对一棵左/右子树均为堆的完全二叉树,“调整”根结点使整个二叉树也成为一个堆。

通俗一点,就是说,在我调整根节点的同时,我将本来无序的二叉树变成一颗有序的二叉树

重点来了!我们需要一个东西来帮助我们实现“筛选”,这里引进两个概念——向上调整,向下调整

向下调整:

• 假设有一个堆heap[1…n],我现在要删除第一个元素(最大的元素),如何维护堆的性质不变?

将根节点删除(后面讲),把最后一个点与根节点交换,若当前的点比左右儿子中任意一个小,那么就交换他们(若两个儿子都比当前节点大,那么取更大的那个交换!)

代码:
//举例一个小根堆
void heap_adjust(int x) {//随便写个名字,x为当前节点的下标
while (x*2<=tot) {//判断是否越界,tot指的是总结点数
int j=x*2;//int一个j假设左儿子更大
if (x*2+1<=tot&&heap[x*2+1]<heap[x*2])j++;//判断左儿子大or右儿子大
if (heap[j]<heap[x])swap(heap[x],heap[j]),x=j;//如果当前节点大于根节点,交换
else break;//不行就结束,说明这个堆有序
}
}

这是一个向下调整的操作,我们用向下调整初步建立堆

假设一个堆heap[1.2.3…99],每次对第一个未知是否子树有序的节点进行向下调整,这样就完成了一个初步的建堆

在这里插入图片描述

合理的不行!

要从后往前依次做操作,为什么这样是对的?因为它是对的 因为你每一次操作能保证他和他的左右儿子是有序的,所以当到根节点的操作时,他的左右子树一定是有序的(tot/2代表第一个非叶子节点)

————————————

这篇关于堆排序(建堆及向下调整)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/371778

相关文章

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

安卓实现弹出软键盘屏幕自适应调整

今天,我通过尝试诸多方法,最终实现了软键盘弹出屏幕的自适应。      其实,一开始我想通过EditText的事件来实现,后来发现,安卓自带的函数十分强大,只需几行代码,便可实现。实现如下:     在Manifest中设置activity的属性:android:windowSoftInputMode="adjustUnspecified|stateHidden|adjustResi

优先队列与堆排序

PriorityQueue 优先级队列中的元素可以按照任意的顺序插入,却总是按照排序的顺序进行检索。无论何时调用remove方法,总会获得当前优先级队列中的最小元素(其实是返回堆顶元素),但并不是对所有元素都排序。它是采用了堆(一个可以自我调整的二叉树),执行增加删除操作后,可以让最小元素移动到根。 堆排序复习 package com.jefflee;import java.util.Arr

如何调整c盘分区大小,怎样把c盘空间调整小些

新买的笔记本电脑回来后发现电脑只分了C盘和D盘两个区,C盘就占了很大的空间,如何调整c盘分区大小,这样可以多腾些空间出来利用呢?虽然Win7有磁盘管理器可以压缩分区实现把C盘调小些,但是它的功能有限,压缩后也是很大一部分空间在C盘浪费,那怎样把c盘空间调整小些呢,下载我们介绍一个工具来完成这些复杂的动作:   1、下载安装分区助手DiskTool中文版。   在主界面上你可以看到C盘有60

java调整日期时间显示格式

SimpleDateFormat是一个以语言环境敏感的方式来格式化和分析日期的类。SimpleDateFormat允许你选择任何用户自定义日期时间格式来运行。 import java.util.*;import java.text.*;public class DateDemo {public static void main(String args[]) {Date dNow =

6.2排序——选择排序与堆排序

本篇博客梳理选择排序,包括直接选择排序与堆排序 排序全部默认排成升序 一、直接选择排序 1.算法思想 每次遍历都选出最小的和最大的,放到序列最前面/最后面 2.具体操作 (1)单趟 每次遍历都选出最小的和最大的。遍历时,遇到更小的,更新min,遇到更大的,更新max (2)单趟变整体 每趟遍历完之后,begin++,end– 程序结构如下 while(begin<end){//

堆与堆排序之初见

堆(本文只提二叉堆,当然也有多叉堆)作为一种数据结构,是一个数组,可以被看成是一个近似的完全二叉树,树上的每一个节点对应数组中的一个元素,并且除了最底层节点外,该树是完全充满的,而且是从左向右依次填充。 我们目前经常听到的名词“堆”已经被引申为“垃圾收集存储机制”,但本文提及的“堆”指的是堆数据结构。 为了后续描述方便,我们定义堆的数组为H,用H.length表示堆数组的大小,用H.size表示堆

Android12——Launcher3文件夹布局修改调整

文章声明:本文是笔者参考良心大佬作品后结合实际需求进行相应的定制,本篇主要是笔者记录一次解析bug笔记,文中可能会引用大佬文章中的部分图片在此声明,并非盈利目的,如涉嫌侵权请私信,谢谢! 大佬原文:安卓开发- 安卓13 Launcher3文件夹预览图、文件夹展开后布局修改-CSDN博客文章浏览阅读305次,点赞5次,收藏8次。Android 13 Launcher3 文件夹预览图标溢出、文件夹展

麦克风MIC 工作原理以及灵敏度调整

https://blog.csdn.net/Charles0512/article/details/50472467?locationNum=6&fps=1 1、先看MIC电路连接 这是个差分输入的例子,MICP2和MICN2是一对差分信号,经过C156的滤波,输入到MIC两端 MIC两引脚分别是到地和供电,上图的R177参数就关系到MIC输入的灵敏度 2、电阻R177影响灵敏度分析 M

ExoPlayer 漫谈之Sonic调整音量

提一个问题:如何在播放视频的时候调整声音的大小? 我们使用Android手机播放视频的时候,发现声音大了,我们手动调低音量;发现声音小了,我们手动调高音量。 这个过程中,都要依赖手动,如果你在不断地刷短视频的时候,如果需要用户不断地手动调整音量键,那这个体验是不能忍受的。 这对我们提了一个要求:我们能在解码音频流的时候通过矩阵运算调整音频原始数据的大小,达到调整音量的目的? 这个思路是可行