当前位置: 首页 > news >正文

手撕排序之堆排序

一、概念:

什么是逻辑结构、物理结构?

逻辑结构:是我们自己想象出来的,就像内存中不存在一个真正的树

物理结构(存储结构):实际上在内存中存储的形式。

堆的逻辑结构是一颗完全二叉树

堆的物理结构是一个数组

之前讲过二叉树可以用两种结构进行表示。

第一种就是链式结构,将一个一个结点进行链接。

第二种就是用数组表示。

数组表示意味着我们就是以数组为结构进行访问,但我们可以通过父子结点的下标关系将其看成树。

下面是孩子与结点的下标关系(需要记住!

思路:

我们将数组想象成一个完全二叉树——首先第一个表示树的根,接下来两个表示根的两个孩子,数组的下面4个表示树的两个孩子的下面一层,以此类推。最后一层不满,前面的都是连续的。

但是进行了上面的步骤后,还是不能将其称为堆。

堆分为两类:

  • 大顶堆(大根堆):树中所有的父亲都大于等于孩子
  • 小顶堆(小根堆):树中所有的父亲都小于等于孩子

一道经典例题(判断一串数字是否是堆)

解题方法:

将第一个数字看作二叉树的根,再往后取两个数字当作根的左右孩子,接着再取4个数,以此类推。直至还原成一个完全二叉树,接着看是不是属于堆的两种类型,如果既不是大顶堆,也不是小顶堆,那么这一串数字就不是堆。

堆的插入:

首先堆在逻辑结构上是一颗二叉树,但逻辑结构是我们自己想象出来的,本质上数据还是存储在数组中,所以我们应该对数组进行修改。

这里的插入我们选择尾插,尾插后有一下几种情况:

1、

直接尾插,不用改变任何顺序

2、

发现尾插顺序不满足大堆或者小堆,记住插入只影响自己的祖先,与其他的祖先没有关系!

所以我们只要改变孩子与祖先的关系,如何根据孩子找到父亲的下标呢?

parent = (child-1)/ 2 即可。

将这两个位置进行交换。

3、最坏的情况

最坏情况下可能会一直到根节点

因此每次交换完,都要进行孩子与父亲的比较

时间复杂度:

我们看最坏的情况,执行次数就是树的高度次,也就是O(logN).

原码:

Swap(HeapDataType* a, HeapDataType* b)
{HeapDataType tmp = *a;*a = *b;*b = tmp;
}void AdujstUp(HeapDataType* 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;}elsebreak;}
}void HeapPush(HP* php,HeapDataType x)
{assert(php);//判断是否需要扩容if (php->capcity == php->size){int newCapcity = php->capcity == 0 ? 4 : php->capcity * 2;//注意realloc的使用方法HeapDataType* tmp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * newCapcity);if (tmp == NULL){perror(realloc);exit(-1);}php->a = tmp;php->capcity = newCapcity;}php->a[php->size] = x;php->size++;//向上调整算法,跟祖先进行比较AdujstUp(php->a, php->size-1);
}

堆的删除:

首先我们需要明确针对堆的删除,我们需要删除的是堆的根节点

思路一(错误)

我们直接将数组的首元素删除,然后移动(memmove)后面的数据内容,但这样极大可能影响了大小堆的结构!

思路二:(向下调整算法)

我们直接将数组的首元素和数组的最后一个元素交换位置,然后size--,删除最后一个元素,也就是根节点。

这时候我们发现根节点的左右子树都是大堆/小堆

然后将根节点与左右节点的较小结点进行比较,如果还小,那么继续交换,直到叶节点为止

以此类推,堆顶的元素是最小的,继续pop,那么次小的元素又到堆顶……

原码:

void AjustDown(HeapDataType* a,int n,int parent)
{int child = parent * 2 + 1;while (child < n){//确定最小孩子if (child + 1 < n && a[child] < a[child + 1])//防止只有左叶子,访问右叶子会越界child++;if (a[parent] < a[child]){Swap(&a[child], &a[parent]);parent = child;child = parent * 2 + 1;}elsebreak;}
}void HeapPop(HP* php)
{assert(php);assert(php->size > 0);Swap(&php->a[0], &php->a[php->size - 1]);php->size--;AjustDown(php->a,php->size,0);
}

小总结:(调整算法的前提)

向上调整算法的前提是:前面的数据内容都是大堆/小堆

向下调整算法的前提是:左右子树的数据内容都是大堆/小堆

TIP:

我们可以根据这个思路,可以实现一个排序算法,也就是堆排序。

时间复杂度:

跟插入一样,都是O(logN)。

堆排序:

1、建堆:

我们可以直接用向上寻找算法进行建堆。——为什么?

建堆有两种方式

第一种就是向上建堆。

利用向上调整算法,每一个插入然后进行向上调整,完成建堆

时间复杂度:O(N) = N*logN

解析:

我们采取最差情况,得到O(h)的表达式,然后再用等式将h替换成n

总体的时间复杂度是O(N) = N*logN

第二种就是向下建堆。

从倒数第一个非叶子结点开始跳(也就是最后一个结点的父亲)

时间复杂度:O(N)

解析:

先假设h是树的高度,N是结点的个数

我们先用树的高度h作为自变量便于计算。最后再用等式进行替换。

考虑最坏的情况:

每层数据的个数 * 向下移动的层数

然后是等差*等比的数列求和,我们采用错位相减法计算。

最后的计算结果是2^h - 1- h.

因为2^h - 1 = n.

所以O(N) = N - log(N+1)

为什么向下调整算法要比向上调整复杂度低呢?

因为向下调整层数越低,向下调整的次数越多,所以是低*高

而向上调整层数越高,向上调整的次数就越多,所以是高*高,并且层数越高,占比越大,最后一层的结点个数就占了50%。

最后一层结点个数多并且向上调整的次数也多

2、排序

如果我们排升序,建大堆

排降序,建小堆

原因:

 建小堆有可能关系全乱了,剩下数据,看成新的完全二叉树,不一定是堆,重新建堆代价太大!

例子:

建大堆:

堆顶跟最后一个位置交换,最大的数据排好了,然后将最后一个元素不列入排序,剩下元素除了根节点其余是堆。剩下的数据由堆顶元素进行向下调整算法,选出次大的,代价是logN。

注意向上调整算法和向下调整算法的前提都是保证数据是堆!

以下是建小堆的堆排序算法

所以一共的时间复杂度O(N) = N*logN.

原码:

void HeapSort(int* a, int n)
{//建堆//建小堆/大堆//向上调整建堆//O(N*logN)/*for (int i = 1; i < n; i++){AdujstUp(a, i);}*///向下调整建堆//O(N),效率比向上调整高for (int i = (n - 1 - 1) / 2; i >= 0; i--)//注意这里的n是数据个数,而公式中的n是下标{AjustDown(a, n, i);}//根节点的值要么最大,要么最小,可以进行排序//这一部分的时间复杂度O(N) = N*logNint end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AjustDown(a, end, 0);end--;}
}

相关文章:

手撕排序之堆排序

一、概念&#xff1a; 什么是逻辑结构、物理结构&#xff1f; 逻辑结构&#xff1a;是我们自己想象出来的&#xff0c;就像内存中不存在一个真正的树 物理结构(存储结构)&#xff1a;实际上在内存中存储的形式。 堆的逻辑结构是一颗完全二叉树 堆的物理结构是一个数组 之…...

【奇想星球】重磅!我们的AIGC共创社区平台上线了!

文章目录 01 前言功能模块 02 相识缘起连接价值平台优势 03 奇想星球04 我们做了什么时间线 05 初心愿景06 可爱的小伙伴们后续开发及招募计划 07 结语 公众号原文链接 01 前言 2023年9月10日&#xff0c;我们的平台网站上线了&#xff01; 奇想星球 | AIGC共创社区平台。网站地…...

2023年数维杯数学建模B题节能列车运行控制优化策略求解全过程文档及程序

2023年数维杯数学建模 B题 节能列车运行控制优化策略 原题再现&#xff1a; 在城市交通电气化进程快速推进的同时&#xff0c;与之相应的能耗增长和负面效应也在迅速增加。城市轨道交通中的快速增长的能耗给城轨交通的可持续性发展带来负担。2018 年&#xff0c;北京、上海、…...

Python--测试代码

目录 1、使用pip安装pytest 1.1 更新pip 1.2 安装putest 2、测试函数 2.1 单元测试和测试用例 2.2 可通过的测试 2.3 运行测试 2.4 未通过的测试 2.5 解决测试未通过 2.6 添加新测试 3、测试类 3.1 各种断言 3.2 一个测试的类 3.3 测试AnonymousSurvey类 3.4 使…...

CentOS 系列版本搭建 Nginx 服务

目录 Nginx 介绍 Nginx 安装 CentOS 系列版本 Nginx 删除 CentOS 系列版本 Nginx 介绍 Nginx 是一个广泛使用的Web服务器和反向代理服务器。 反向代理和负载均衡&#xff1a;Nginx支持反向代理和负载均衡&#xff0c;能够分发请求到多个后端服务器&#xff0c;提高了可用性…...

目标检测YOLO实战应用案例100讲-基于机器视觉的输电线路小目标检测和缺 陷识别(下)

目录 3.3.1 输电线路所有尺寸目标检测性能对比 3.3.2 输电线路小目标检测性能对比...

argparse--命令行参数解析库

文章目录 位置参数help ->描述信息type -> 被转换的类型 可选参数action ->动作基本类型 (store_true)短选项 结合位置参数和可选参数choiceaction ->动作基本类型 (count)default -> 默认值 argparse模块使编写用户友好的命令行变得容易 接口。程序定义了它需要…...

elasticsearch4-文档操作

个人名片&#xff1a; 博主&#xff1a;酒徒ᝰ. 个人简介&#xff1a;沉醉在酒中&#xff0c;借着一股酒劲&#xff0c;去拼搏一个未来。 本篇励志&#xff1a;三人行&#xff0c;必有我师焉。 本项目基于B站黑马程序员Java《SpringCloud微服务技术栈》&#xff0c;SpringCloud…...

阿里云服务器上CentOS 7.6使用rpm包安装MySQL 8.0.31

我这里下载的是最新版本&#xff0c;需要到MySQL官网最新版本下载地址。 要是想要下载以前的版本需要到MySQL以前版本网址中。 1&#xff09;先使用wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar&#xff08;这个网址现在已经不…...

redis未授权漏洞

redis未授权漏洞是什么&#xff1f; Redis 默认情况下会绑定在 0.0.0.0:6379&#xff0c;这样将会将 Redis 服务暴露到公网上&#xff0c;如果在没有开启认证的情况下&#xff0c;可以导致任意用户在可以访问目标服务器的情况下未授权访问Redis以及读取 Redis的数据 它有什么危…...

详解3dMax中渲染线框的两种简单方法

在3dMax中渲染线框是你在某个时候想要完成的事情&#xff0c;例如为了演示分解步骤&#xff0c;或是仅仅为了在模型上创建线框覆盖的独特效果。为三维模型渲染线框最常见的原因是能够在模型上显示干净的拓扑。这篇文章将带你了解在3dMax中渲染三维模型线框的两种最常见、最简单…...

Git - Git 工作流程

文章目录 Git WorkFlow图解小结 Git WorkFlow Git Flow是一种基于Git的工作流程&#xff0c;确实利用了Git作为分布式版本控制系统的优势。 本地代码库 (Local Repository): 每个开发者都维护自己的本地代码库&#xff0c;这是Git分布式性质的体现。本地代码库包含了完整的项目…...

ARM如何利用PMU的Cycle Counter(时钟周期)来计算出CPU的时钟频率

本章将学习如何利用ARM PMU的Cycle Counter&#xff0c;来计算出CPU的时钟周期&#xff0c;从而计算出CPU的时钟频率。在介绍计算方法前&#xff0c;有必要先介绍下什么是时钟周期、机器周期以及指令周期。 如何计算出CPU的时钟频率 一&#xff0c;时钟周期&#xff0c;机器周…...

56资源网系统源码搭建知识付费-含源码

内置了上万条数据资源 大致功能&#xff1a; 支持免费与付费&#xff08;增加了插件付费插件&#xff09;支持侧边栏支持添加各类型广告&#xff08;你所能用到的基本都有&#xff09;.支持网盘下载模块支持所有页面自定义支持文章页三方跳转支持添加页面支持自定义采集&#…...

【运营版】仿东郊到家上门服务app小程序开发同城美容家政预约推拿足浴SPA技师派单源码

套餐一:源码=小程序端+公众号端+APP端=280元 套餐二:全包服务 包服务器+域名+APP+认证小程序+H5+PC=1000元 后端:系统后端使用PHP语言开发 前端:前端使用uniapp进行前后端分离开发 用户端功能模块:技师选择 预约服务 优惠券 订单 技师服务...

uniapp项目实践总结(十五)使用websocket实现简易聊天室

导语:在一些社交软件中,经常可以看到各种聊天室的界面,接下来就总结一下聊天室的原理个实现方法,最后做一个简易的聊天室,包括登录/登出、加入/离开房间、发送接收聊天消息等功能。 目录 准备工作原理分析组件实现实战演练服务端搭建案例展示准备工作 在pages/index文件夹…...

论文阅读之Learning and Generalization of Motor Skills by Learning from Demonstration

论文阅读其实就是用自己的话讲一遍&#xff0c;然后理解其中的方法 0、论文基本信息 为什么阅读此篇论文&#xff1a;因为它是DMP经典论文&#xff0c;被引多次&#xff0c;学史可以明智&#xff0c;了解最初机理。 论文题目&#xff1a;Learning and Generalization of Moto…...

SpringCloud中的Eureka的集群配置

微服务框架中最为重要的就是注册中心&#xff0c;如果只是单注册中心&#xff0c;一旦出现问题&#xff0c;容易导致整个微服务环境不可用&#xff0c;所以建议注册中心集群。 目前SpringCloud框架中使用Eureka作为注册中心&#xff0c;本文简单介绍一下Eureka的集群配置&…...

10 Ubuntu下配置STMCubeMX与CLion IDE联合环境搭建(不包含下载CLion的教程)

序言 果然作为一名测控系的学生&#xff0c;纯搞视觉多少还是有点与专业脱节&#xff0c;决定入坑嵌入式。选择STM32进行入门&#xff0c;并且使用CubeMX加CLion作为我的第一个真正意义上的嵌入式开发环境&#xff08;大一的时候玩过一段时间&#xff0c;但是没什么技术&#…...

负载均衡原理及应用

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

视频讲解|1033含sop的配电网重构(含风光可多时段拓展)

目录 1 主要内容 程序特点 讲解重点 2 视频链接 1 主要内容 该视频为含sop的配电网重构matlab代码讲解&#xff0c;对应资源下载链接为含sop的配电网重构&#xff08;含风光|可多时段拓展&#xff09;&#xff0c;程序主要内容是&#xff1a;针对含sop的配电网重构模型&…...

uni-app监听页面滚动

在uni-app中可以通过监听页面滚动事件来实现滚动效果或响应滚动事件 在需要监听滚动的页面或组件中&#xff0c;添加一个scroll元素&#xff0c;用于容纳内容并实现滚动效果。 <template><view class"container"><scroll-view scroll-y scroll"…...

[字符串和内存函数]strcmp字符串函数的详解和模拟

strcmp函数 strcmp函数是一个用于比较两个字符串的C标准库函数。它的原型为&#xff1a; int strcmp(const char* str1, const char* str2);strcmp函数会比较str1和str2两个字符串的字符序列&#xff0c;并返回一个整数值来表示它们之间的大小关系。返回值的含义如下&#xff…...

zookeeper 常见问题处理

调整jvm参数 [rootvm-02 conf]# cat /opt/app/zookeeper-3.4.14/bin/zkEnv.sh |grep java.env -A3 -B3ZOOCFG"$ZOOCFGDIR/$ZOOCFG"if [ -f "$ZOOCFGDIR/java.env" ] then. "$ZOOCFGDIR/java.env" fiif [ "x${ZOO_LOG_DIR}" "x&…...

repo 命令

repo命令是Google开发的用于管理Android版本库的一个工具。 repo命令并不是用于取代git&#xff0c;而是用Python对git进行了一定的封装&#xff0c;简化了对多个Git版本库的管理。 repo init -u -b -m <manifest 文件名称> repo sync 相当于 git clone 获取 git remote…...

一、 计算机网络概论

一、计算机网络概论 1、计算机网络概述 1.1、概念 计算机网络是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统 是一些互连的、自治的计算机系统的集合 以能够相互共享资源的方…...

从零学习开发一个RISC-V操作系统(一)丨计算机组成原理相关知识与RISC-V指令集简介

本篇文章的内容 一、计算机组成原理的相关知识1.1 计算机的硬件组成1.2 程序的存储与执行1.3 程序语言的设计和进化1.4 存储设备的层次结构1.5 操作系统 二、RISC-V的指令集ISA简介2.1 什么是ISA2.2 复杂指令集&#xff08;CISC&#xff09;和精简指令集&#xff08;RISC&#…...

C++ - 异常介绍和使用

前言 我们在日常编写代码的时候&#xff0c;难免会出现编写错误带来程序的奔溃&#xff0c;或者是用户在使用我们编写的程序时候&#xff0c;使用错误所带来程序的奔溃。 在C 当中 可以对你觉得可能发生 错误 的地方在运行之前进行判断&#xff0c;发生错误可以给出提示。 C…...

iText实战--在现有PDF上工作

6.1 使用PdfReader读取PDF 检索文档和页面信息 D:/data/iText/inAction/chapter03/image_direct.pdf Number of pages: 1 Size of page 1: [0.0,0.0,283.0,416.0] Rotation of page 1: 0 Page size with rotation of page 1: Rectangle: 283.0x416.0 (rot: 0 degrees) Is reb…...

SQL优化--count优化

select count(*) from tb_user ;在之前的测试中&#xff0c;我们发现&#xff0c;如果数据量很大&#xff0c;在执行count操作时&#xff0c;是非常耗时的。 MyISAM 引擎把一个表的总行数存在了磁盘上&#xff0c;因此执行 count(*) 的时候会直接返回这个 数&#xff0c;效率很…...

360的网站怎么做/新网站友链

吟诵&#xff0c;不为吟诵 我们吟诵&#xff0c;不是为了吟诵。我们推广吟诵&#xff0c;也不是为了推广吟诵。我们在做一项大事业——中国文化的重建&#xff0c;吟诵只是其中的一项&#xff0c;虽然是很重要的一项。一百年来&#xff0c;我们走了一条弯路。“五四”先哲们以为…...

wordpress主题 tob/推广app的软文案例

每天读一篇一线开发者原创好文问题引入&#xff1a;项目发展&#xff0c;自动化测试需要使用python模拟客户端发送http2.0请求。选型&#xff1a;目前网上盛行的python模拟客户端发送http2.0的库主要为hyper&#xff0c;毫无疑问&#xff0c;大胆一试。选型参考&#xff1a;htt…...

网站开发形象设计要求/怎样联系百度客服

window.history 我们可以通过window.history的两个方法来控制浏览器的路由改变&#xff0c;但不会让浏览器刷新页面。 pushState 会追加浏览器的路由历史&#xff0c;但不会刷新页面&#xff0c;可以用这种方式来实现前端路由的控制。 history.pushState(state, title[, ur…...

青岛cms建站系统/seo是干啥的

自己编写了一个工具类&#xff0c;处理页面提交json格式数据到后台&#xff0c;再进行处理成Java对象数据 1、DTO&#xff1a;Data Transfer Object&#xff0c;数据传送对象 2、对于日期格式的问题&#xff0c;也已经处理 3、json-lib-2.2.2-jdk13.jar &#xff08;2.1在日期数…...

松江做网站/帆软社区app

A: 今天同学遇到了一个FCKeditor如何删除文件中图片的问题&#xff0c;我也是第一次遇到&#xff0c;为了解决这个问题从网上搜到了一点资料。与大家共享一下。最近在做项目时做了这样一个功能&#xff0c;已减少垃圾图片&#xff01;用正则表达式得到图片的路径与名称。 PageV…...

大连金州代做网站公众号/快速排名教程

马哲包括5大部分即唯物论&#xff0c;辩证法&#xff0c;认识论&#xff0c;历史唯物论&#xff0c;资本主义本质论。 其中辩证法又包括&#xff1a; 1.两大特征&#xff1a;&#xff08;1&#xff09;普遍联系&#xff08;2&#xff09;永恒发展。 2.三大规律&#xff1a;&…...