堆排序的概念

040.堆排序的概念和实现 <!-- TOC --> <ul> <li><a href="#1-%E5%A0%86%E7%9A%84%E6%A6%82%E5%BF%B5">1. 堆的概念</a><ul> <li><a href 阅读详情


选择排序:在每一趟待排元素中选取关键字最小(或最大)的元素加入有序子序列

选择排序分为:

  • 简单选择排序
  • 堆排序

一、堆(Heap)的基本概念

若n个关键字序列L[1…n]满足下面某一条性质,则称为堆(Heap):

  • 若满足:L(i)≥L(2i)且L(i)≥L(2i+1)(1≤i≤n/2)–大根堆
  • 若满足:L(i)≤L(2i)且L(i)≤L(2i+1)(1≤i≤n/2) --小根堆

1.1 引入二叉树的顺序存储

在这里插入图片描述
有此可见,堆逻辑上可理解为一个顺序存储的完全二叉树

  • 大根堆–根>左,右的完全二叉树
  • 小根堆–根<左,右的完全二叉树

二、建立大根堆

基本思路:把所有分支结点检查一遍,判断是否满足大根堆的要求,如果不满足,则进行调整。

根据完全二叉树的性质:

  • 2i<n
  • 2i+1<n
  • 叶子结点:i>n/2
  • 分支结点: i ≤ n / 2 i\leq n/2 i≤n/2

故只需比较分支结点与其孩子结点的大小。找到最靠后的分支结点开始检查,如果不满足大根堆的条件,从左右孩子结点中挑较大的一个与根结点交换。接着不断从下往上调整(数组从后往前遍历)。


举例帮助理解:
在这里插入图片描述
i=8;只需检查 i ≤ 4 i\leq 4 i≤4的结点即可,即为上图圈出来的结点。
二叉树从下往上调整,故从09开始,接着检查78,然后是17,最后是53。
数组对应从后往前检查,i=4向前遍历。


代码实现

建立大根堆:

void buildMaxHead(int arr[], int length) {
	for (int i = length / 2; i >= 1; i--) {//从后往前遍历数组
		HeadAdjust(arr, i, length);
	}
}

将以k为根的子树调整为大根堆:

void HeadAdjust(int arr[], int k, int len) {
	arr[0] = arr[k];//key
	for (int i = 2 * k; i <= len; i*=2) {//延key不断向下检查子节点
		if (arr[i] < arr[i + 1] && i + 1 <= len) { //将i指向较大子孩子
			i++;
		}
		if (arr[0] >= arr[i])//当满足大根堆,退出
			break;
		else {
			arr[k] = arr[i];
			k = i;//修改k值,继续向下检查
		}
	}
	arr[k] = arr[0];//将key放入最后检查的位置
}

三、基于大根堆进行排序

堆排序:每一趟将堆顶元素加入有序子序列(与待排序序列中的最后一个元素交换)

并将待排序元素序列再次调整为大根堆(小元素不断“下坠”)

举例帮助理解
在这里插入图片描述
此时已经完成一次堆排序,堆顶元素为最大元素
在这里插入图片描述
将堆顶元素队列末尾元素互换。接着不断进行HeadAdjust(arr,1,len-1)


完整代码实现

#include<iostream>
using namespace std;
int N;
int arr[100050];
void HeadAdjust(int arr[], int k, int len) {
	arr[0] = arr[k];
	for (int i = 2 * k; i <= len; i *= 2) {
		if (arr[i] < arr[i + 1] && i + 1 <= len) { //将i指向较大子孩子
			i++;
		}
		if (arr[0] > arr[i])
			break;
		else {
			arr[k] = arr[i];
			k = i;
		}
	}
	arr[k] = arr[0];
}
void buildMaxHead(int arr[], int length) {
	for (int i = length / 2; i >= 1; i--) {
		HeadAdjust(arr, i, length);
	}
}

int main() {
	cin >> N;
	for (int i = 1; i <= N; i++) {
		cin >> arr[i];
	}
	buildMaxHead(arr, N);//建立大根堆
	//基于大根堆的堆排序
	for (int i = N; i >= 1;) {
		int t = arr[i];
		arr[i] = arr[1];
		arr[1] = t;
		HeadAdjust(arr,1,--i);
	}
	for (int i = 1; i <= N; i++) {
		if (i != 1)
			cout << " ";
		cout << arr[i];
	}
}
堆排序详细图解(通俗易懂) 什么是堆 堆是一种叫做完全二叉树的数据结构,可以分为大根堆,小根堆,而堆排序就是基于这种结构而产生的一种程序算法。 堆的分类 大根堆:每个节点的值都大于或者等于他的左右孩子节点的值 小根堆:每个结点的值都小于或等于其左孩子和右孩子结点的值 两种结构映射到数组为: 大根堆: 小根堆: //父-->子:i--->左孩子:2*i+1, 右孩子:2*i+2; //子-->父:i--->(i-1)*2;(i为下标元素) 排序思想 1.首先将待排序的数... 阅读详情

相关推荐

数据结构 堆排序 输出每一趟结果

描述 用函数实现堆排序,并输出每趟排序的结果 Input 第一行:键盘输入待排序关键的个数n 第二行:输入n个待排序关键字,用空格分隔数据 Output 第一行:初始建堆后的结果 其后各行输出交换堆顶元素并调整堆的结果,数据之间用一个空格分隔 Sample Input 10 5 4 8 0 9 3 2 6 7 1 Sample Output 9 7 8 6 4 3 2 5 0 1 8 7 3 6 4 1 2 5 0 9 7 6 3 5 4 1 2 0 8 9 6 5 3 0 4 1 2 7 8 9 5 4 3 0 2 1 6 7 8 9 4 2 3 0 1 5 6 7 8 9 3 2 1 0 4 5 6 7 8 9 2 0 1 3 4 5 6 7 8 9 1 0 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

认识堆排序的排序过程

1,实用的排序算法:选择排序 (1)选择排序的基本思想是:每一趟(例如第i趟,i=0,1,2,3,……n-2)在后面n-i个待排序元素中选择排序码最小的元素,作为有序元素序列的第i个元素。待到第n-2趟做完,待排序元素只剩下一个,就不用再选了。 (2)三种常用的选择排序方法 1>直接选择排序 2>锦标赛排序 3>堆排序 其中,直接排序的思路和实现都比较简单,并且相比其他排序算法,直接

razorEdge的博客 1万+

error C2039: “int_least8_t”: 不是“`global namespace'”的成员

在向H.265的测试软件HM16.0中配置boost的时候,发现 include &lt;boost/cstdint.hpp&gt;的时候总是会报错:错误 11 error C2039: “int_fast16_t”: 不是“`global namespace'”的成员 D:\Program Files\Caffe\VSContact\boost_1_58_0\boost\cstdint.hpp ...

flyerene的博客 1万+

必学排序算法——堆排序

堆排序算法是必须掌握的一种基础算法,在一些比较出名的竞赛acm、蓝桥杯,并且在一些公司面试题中都可能会出现,而且作为简单题我们必须要拿下,所以我们要引起重视,下面让我们来深入了解堆排序算法。堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。堆是一个近似完全二叉树的结构,分为最大堆和最小堆。在最大堆中,父节点的值总是大于或等于其子节点的值;而在最小堆中,父节点的值总是小于或等于其子节点的值。堆排序通常使用最大堆来升序排序数组,使用最小堆则可以降序排序数组。

ycs66的博客 3956

三边定位的最小二乘法运用

已知:条件基站到移动台的距离D,基站的坐标(xi,yi,zi) 求:移动台的坐标(x,y,z) 运用最小二乘法的核心是找到最小二乘法的矩阵形式即 Ax=B 在本次实验中通过三边定位计算得到 A=[A;2*(xi-x1),2*(yi-y1),2*(zi-z1]; %系数矩阵A b=[b;D1^2-Di^2+xi^2+yi^2+zi^2-x1^2-y1^2-z1^2]; %增广矩阵b

qq_26250141的博客 1万+

数据中心光模块升级实录:从200G QSFP56到400G QSFP-DD的踩坑指南

本文记录了数据中心从200G QSFP56升级至400G QSFP-DD光模块的完整实战经验。文章深入剖析了升级过程中面临的兼容性、链路预算、布线、散热与功耗管理等核心挑战,并提供了具体的解决方案与排坑指南,为高速网络升级提供了宝贵的实践参考。

butter的博客 479

堆排序每一趟的结果_八大排序-堆排序(手写堆排序)

闲聊最近看完一个电视剧,猪脚是胃无限和难忘鸡。比较奇怪的是整个电视剧没有讲爱得死去活来的男女之情反而讲的是男男之间纯纯的知己之情(基情),不过别说还挺好看。有种感觉就像:天下人负你又如何,我定然站你这边...让我想到了当今社会的一些人,这类人习惯权衡利弊后“战队”,或察言观色后随波逐流不顾真理事实。这部剧表达的三观就像一股清流,人生难得一知己,让我内心颇有触动。很喜欢胃无限说的一句话:管他熙熙攘攘...

weixin_39917437的博客 4798

kubedns-coredns部署pod出现not ready问题

文章目录遇到的问题1、发现问题2、排查问题3、解决方法 coredns的实例health_check不通过的问题,排查和解决方法 遇到的问题 1、发现问题 pod启动但是未ready 查看是readiness失败 使用对应的URL进行curl,发现真的返回503 2、排查问题 查看错误日志,发现一堆这个错误"waiting on : kubernetes" 网上相关的问题解答 这个跟测试场景不一样,这个案例是开了防火墙,可以确认我这个案例的机器没有开防火墙,但它提醒了一点,coredns是需要访问ap

u012533481的博客 2844

详解堆排序

1.堆排序定义 堆排序是一种树形选择排序方法,特点是在排序的时候,可以将拥有n个关键字的数组或其他结构看做一个完全二叉树。 如图: 堆的定义:n个关键字序列L(1...n)称为堆,当满足: L(i) <= L(2i) 且 L(i) <= L(2i+1) ( 1 <= i <= [n/2] ) 也就是说小于左右孩子 ,称之为小顶堆 L(i) >= L(2i) 且 L(i) >= L(2i+1) ( 1 <= i <= [n/2] ) 也就是...

qq_51950769的博客 5064

c++ webrtc基础(1) :webrtc源码下载与编译、项目模块介绍、学习资料推荐

本篇博客介绍webrtc源码的下载与编译,以及推荐webrtc学习资料。 源码下载 电脑环境:win10/win11 64bit,合理的上网环境,没有合理的网络环境无法拉取、下载webrtc代码和工具,宽带速度要快,尽量50M. 主要步骤如下: (1) 安装git (2) 打开cmd控制台,下载google开发工具depot_tools: git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git (3) 新建一个目

琅嬛福地 3293

rknn-toolkit推理yolov5-face.rknn模型--python代码

import os import urllib import traceback import time import sys import numpy as np import cv2 from rknn.api import RKNN ONNX_MODEL = 'yolov5s.onnx' RKNN_MODEL = 'yolov5s.rknn' IMG_PATH = './bus.jpg' DATASET = './dataset.txt' QUANTIZE_ON = True BOX_THR.

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 3079

3.11 堆的概念及堆排序思路

Chapter3: 更好的查找与排序算法 11. 堆的概念及堆排序 [1] 图解排序算法(三)之堆排序 讲得很好,这里相当于写个精简大纲版并将java代码转换为C++代码 堆的相关概念 堆排序概述 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆的概念 堆是具有以下...

bloger博客 362

SAP UI5 本地开发工具 fiori-tools-proxy 中间件详解及使用场景

该中间件基于 http-proxy-middleware 库实现,分为 ui5 资源代理和 backend 代理两大模式,并可与 fiori run 或 ui5 serve 命令无缝集成,通过配置 ui5.path、ui5.url 以及 backend.path、backend.url 等参数,实现与目标系统的灵活对接和安全配置 (就后端系统代理而言,fiori-tools-proxy 内置 @sap-ux/backend-proxy-middleware,可将以指定前缀(如。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 516

《堆的概念和结构以及堆排序》

用C语言实现堆以及堆排序和TopK

m0_58950498的博客 366

Python 爬虫实战:微信搜一搜内容深度爬取(含搜索结果解析与企业级架构设计)

在信息爆炸的时代,微信搜一搜已成为海量信息获取的重要入口。无论是个人知识探索,还是企业舆情监控,掌握微信搜一搜内容的深度爬取能力具有巨大价值。本文将从基础原理到企业级实现,全面解析微信搜一搜爬虫的开发过程。

yansideyucsdn的博客 2455

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

数据结构堆的概念&&堆排序的思想以及算法过程详解(图文)

一、堆的概念 介绍堆之前,首先来看二叉树 Binary Tree。 二叉树是树的一种,主要的特点是二叉树的所有节点最多只有两个叶节点。除此之外没有别的要求。 Complete Binary Tree(完全二叉树): 二叉树的一种。在完全二叉树当中,除了最后一层之外,所有层的节点都是满的,且最后一层的节点也是从左到右的。优先填满左边的节点。 Full Binary Tree(满二叉树): 二叉树的一种。满二叉树的所有层,包括最后一层,都是满的。也就是说,除了最后一层的节点外所有的节点都有两个子节点。 这两

LifeGoesOn 1571

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

数据结构之二叉树的超详细讲解(2)--(堆的概念和结构的实现,堆排序和堆排序的应用)

之前发布过数据结构之二叉树的超详细讲解(1)--(树和二叉树的概念和结构),今天重点讲解堆的概念和结构的实现,堆排序和堆排序的应用,感兴趣的宝子们赶紧点赞收藏起来吧!💓💓💓 ​

wer24_25的博客 2808

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

二叉树(一)———树的概念 + 堆与堆排序

详细讲解了树的常用概念以及二叉树,同时实现二叉树的线性结构——堆和堆排序

weixin_64099089的博客 1330

堆的概念,创建,插入,删除以及堆排序

堆的概念 如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中,并满足:   Ki &lt;= K2*i+1 且 Ki&lt;= K2*i+2 (Ki &gt;= K2*i+1 且 Ki &gt;= K2*i+2) i = 0,1,2…,则称为小堆(或大堆)。 小堆(大堆)中:任一结点的关键码均小于(大于)等于它的左右...

Damn_Yang的博客 288

堆的概念,堆的创建和时间复杂度证明,堆排序,TopK问题。

或许只有学习能让彷徨的我,心安吧!

qq_55439426的博客 2069

堆的概念和结构以及堆排序

堆的概念和堆排序的时间复杂度的讲解

wutongguo的博客 1319

堆排序之堆的概念—插入、删除、建堆

内容会持续更新,有错误的地方欢迎指正,谢谢!堆的性质 性质:完全二叉树 或 近似完全二叉树(不是满二叉树的完全二叉树)。 分类:最大堆:父节点的值不小于子节点;最小堆:父节点的值不大于子节点。 左右子节点:没有大小的顺序。 堆的存储: 一般都用数组来存储堆。下标为i的节点的父节点的下标为(i–1)/2。根节点的左右子节点下标分别为 2∗i+1 和 2∗i+2。例如:下标为0的节点左右子节点的下标

陈云佳的专栏 7358

堆排序---从堆的概念开始介绍

将原堆的根与两个子堆的根中较小(大)的比较,若大于则交换,交换后再与其两个子堆的根中较小(大)的比较,大于交换,循环往复,直到其小于两个子堆的根,或者到达叶子节点。由于堆是由数组表示的,当完成对一个完全二叉树建堆后,把根元素与数组的最后一个元素交换,再把数组长度减小1,再建堆,循环往复。堆常用数组表示,数组的下标为堆的编号-1,由此可以利用完全二叉树的数学关系,通过一个节点找到它的父亲、左右儿子,来遍历整个堆。这样,9为根,其两个子树仍然是小堆,符合向下调整算法,循环往复,实现数值的从大到小排序。

H_238的博客 581

堆和栈的概念和区别 python_浅谈堆排序

堆排序可以做什么首先应该弄清楚堆排序可以解决什么问题,答案是显而易见的:排序。说得通俗点儿就是对一组无序的数字进行调整,使其按照从大到小或者从小大到的顺序有序排列。我们习惯性的采用数组这一数据结构来记录一系列有序或者无序的数据。故我们可以借助堆排序这种方法,将以下无序数组:453261调整为有序数组:123456以下讲解的所有内容都是为了将上述无序数组经过堆排序后调整为从大到小的有序数组。什么是堆...

weixin_39792751的博客 135

【初探】 堆排序

堆排序介绍● 堆排序(Heap Sort): 是指利用堆这种数据结构所设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn) (堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法),它也是不稳定排序。注意: 在学习堆排序之前,有必要了解堆!若读者不熟悉堆, 建议先了解堆(建议可以通过二叉堆,左倾堆,斜堆,二项堆或斐波那契堆等

TAOTAO 578

排序方法之堆排序

转自 http://blog.youkuaiyun.com/liuzuyi200/article/details/9858179 堆排序的实现 (—)创建初始堆 (二)堆排序 在创建初始堆之前首先要了解一些关于堆的概念,还需要了解一些关于平衡二叉树的内容  (1)堆的节点数 =n/2; 并且是只舍不入;  (2)最后一个堆结点=(n/2)-1;   (3)对于任意结点a[x],可以找到它子结

dingkaich的专栏 354
上一篇: 哈夫曼树、带权路径长度、前缀编码 的概念
下一篇: xmu 离散数学 卢杨班作业详解【1-3章】
快苏排序OAO
博客等级 码龄5年 273粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快苏排序OAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值