第八章 排序 七、堆排序

news2024/9/30 7:15:09

目录

一、堆的概念

1、大根堆

2、小根堆

二、建立大根堆

1、举个例子,我们要让一个序列变换成为一个大根堆

2、我们把序列看成一棵完全二叉树,而完全二叉树有以下特性:

3、在此序列中,由于是从1开始的序列,所以分支结点为1到4

4、我们从后往前检查,首先就检查下标为4的结点09

5、下一个检查结点78,通过比较发现87为更大的孩子,于是进行互换

6、继续检查结点17,通过比较发现45为更大的孩子,于是进行互换

7、之后检查结点53,通过比较发现87为更大的孩子,于是进行互换

8、最后再次检查结点53,通过比较发现78为更大的孩子,于是进行互换

9、最终我们得到了一个大根堆

三、建立大根堆的代码实现

四、堆排序算法思想

五、例子

1、我们有如下序列,我们要将此序列使用堆排序进行升序排序

2、让序列首尾元素互换,如此一来,我们就将最大元素放到了队尾。

3、可是现在的序列又失去了大根堆的特性,所以我们要重新将它化为大根堆,只是这次我们要把87排除在外,因为它已经排好序了

4、这次我们又让序列中的首尾元素互换,也就是78和53,将第二大的元素找到

5、再次进行大根堆化

6、再次首尾互换

7、经历n-1次处理,就能得到最终的升序序列

六、代码实现

七、验证

八、算法效率分析

九、稳定性

十、总结


一、堆的概念

1、大根堆

简单来说,大根堆就是根结点大于它的左右孩子结点的一棵完全二叉树

2、小根堆

同样的,对与小根堆来说,它就是根结点小于它的左右孩子结点的一棵完全二叉树

二、建立大根堆

1、举个例子,我们要让一个序列变换成为一个大根堆

2、我们把序列看成一棵完全二叉树,而完全二叉树有以下特性:

  1. 分支结点的下标为[0 到 \frac{n}{2}]
  2. 若一个结点的下标为i,则它的左孩子下标为2i,右孩子下标为2i-1,父节点的下标为\frac{i}{2}.

3、在此序列中,由于是从1开始的序列,所以分支结点为1到4

我们要检查每个分支结点的左右孩子是否满足大根堆的特性,根>=左右

4、我们从后往前检查,首先就检查下标为4结点09

它的左孩子为32,无右孩子,而且32大于9,不满足大根堆的特性,所以让9和32互换,若左右孩子都更大,则取更大的那个

5、下一个检查结点78,通过比较发现87为更大的孩子,于是进行互换

互换后为下图

6、继续检查结点17,通过比较发现45为更大的孩子,于是进行互换

互换后为下图

7、之后检查结点53,通过比较发现87为更大的孩子,于是进行互换

互换后为下图

但是互换后又有新的问题出现了,以53为根的子树再次不满足大根堆的特性,于是我们要继续互换。(小元素不断”下坠“

8、最后再次检查结点53,通过比较发现78为更大的孩子,于是进行互换

9、最终我们得到了一个大根堆

三、建立大根堆的代码实现

void HeadAdjust(int a[],int k,int len){//k是分支结点的边界
    a[0] = a[k];//将分支结点存在下标为0的地方
    for (int i = 2*k; i <= len; i*=2) {//检查左孩子
        if (i<len&&a[i]<a[i+1]){//找到更大的孩子
            i++;
        }
        if(a[0]>=a[i]){//满足大根堆特性
            break;
        }else{//不满足就交换
            a[k] = a[i];
            k = i;
        }
    }
    a[k] = a[0];
}

void BuildMaxHeap(int a[],int len){
    for (int i = len/2; i > 0; i--) {//遍历所有的分支结点
        HeadAdjust(a,i,len);//调用函数对序列进行大根堆化
    }
}

四、堆排序算法思想

每次都将大根堆的序列第一个元素和序列最后一个元素互换。

五、例子

1、我们有如下序列,我们要将此序列使用堆排序进行升序排序

2、让序列首尾元素互换,如此一来,我们就将最大元素放到了队尾。

3、可是现在的序列又失去了大根堆的特性,所以我们要重新将它化为大根堆,只是这次我们要把87排除在外,因为它已经排好序了

4、这次我们又让序列中的首尾元素互换,也就是78和53,将第二大的元素找到

5、再次进行大根堆化

6、再次首尾互换

7、经历n-1次处理,就能得到最终的升序序列

六、代码实现

#include "bits/stdc++.h"
using namespace std;

void HeadAdjust(int a[],int k,int len){//k是分支结点的边界
    a[0] = a[k];//将分支结点存在下标为0的地方
    for (int i = 2*k; i <= len; i*=2) {//检查左孩子
        if (i<len&&a[i]<a[i+1]){//如果该分支结点满足大根堆的特性
            i++;//就检查下一个分支结点
        }
        if(a[0]>=a[i]){//满足大根堆特性
            break;
        }else{//交换
            a[k] = a[i];
            k = i;
        }
    }
    a[k] = a[0];
}

void BuildMaxHeap(int a[],int len){
    for (int i = len/2; i > 0; i--) {//遍历所有的分支结点
        HeadAdjust(a,i,len);//调用函数对序列进行大根堆化
    }
}

void HeapSort(int a[],int len){
    BuildMaxHeap(a,len);//建立大根堆
    for (int i = len; i > 1; i--) {//进行n-1次处理
        int temp = a[1];//首尾交换
        a[1] = a[i];
        a[i] = temp;
        HeadAdjust(a,1,i-1);//每次首位交换后都要检查是否为大根堆
    }
}


int main(){
    int count,arr[10];
    scanf("%d",&count);//输入数组长度
    for (int i = 1; i <= count; ++i) {
        scanf("%d",&arr[i]);//输入数组
    }
    HeapSort(arr,count);//调用排序函数
    for (int i = 1; i <= count; ++i) {
        printf("%d ",arr[i]);//输出数组
    }
    return 0;
}

七、验证

八、算法效率分析

一个结点,每“下坠”一层,最多只需对比关键字2次。

若树高为h,某结点在第i层,则将这个结点向下调整最多只需要“下坠” h-i层,关键字对比次数不超过2(h-i)

建堆的时间复杂度

总的时间复杂度和空间复杂度

九、稳定性

堆排序是不稳定的

十、总结

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

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

相关文章

海外网红营销:赢得年轻人的心,打破传统的秘密武器

随着数字时代的崛起&#xff0c;社交媒体已经成为了年轻人生活的一部分。年轻人在社媒平台上创造和分享内容&#xff0c;构建着他们的社交圈子&#xff0c;也塑造着全球的文化和趋势。对于企业来说&#xff0c;赢得年轻人的心已经成为了一项关键任务&#xff0c;而海外网红营销…

linux环境下 查看 进程内存占用情况

新版本 -o %MEM 按内存排序 top -o %MEM -b -n 1 | grep java | awk {print "PID: "$1" \t MEM: "$6" \t %CPU: "$9"% \t %MEM: "$10"%"} 通过指令找到内存消耗量最大的几个进程 查看内存消耗情况 top -b -n 1 | grep jav…

Linux从时间服务器同步时间

一、基本设定 自己的时间服务器&#xff1a;111.11.11.111 二、操作 查看当前时间命令&#xff1a;date&#xff0c;发现时间不一致。 同步命令&#xff1a;/usr/sbin/ntpdate 111.11.11.111 然后等待同步完成即可。 如果同步命令不可用&#xff0c;需要先安装Ntp服务&…

使用运放产生各种波形

目录复制 文章目录 RC正弦振荡电路文氏电桥振荡电路移项式正弦波振荡电路 集成函数发生器运算放大器驱动电容性负载峰值检波多通道运放未使用的运放接法 RC正弦振荡电路 文氏电桥振荡电路 这个振荡器起振条件RF > 2R1,起振后又希望RF 2R1产生矛盾怎么办&#xff1f; 将RF换…

LeetCode 1251. 平均售价

题目链接&#xff1a;1251. 平均售价 题目描述 表&#xff1a;Prices Column NameTypeproduct_idintstart_datedateend_datedatepriceint (product_id&#xff0c;start_date&#xff0c;end_date) 是 prices 表的主键&#xff08;具有唯一值的列的组合&#xff09;。 price…

开发者指南:如何集成一对一直播美颜SDK到你的应用中

本文将为开发者们提供一个详细的指南&#xff0c;教你如何将一对一直播美颜SDK集成到你的应用中&#xff0c;以提供更具吸引力的直播体验。 -为什么选择一对一直播美颜SDK&#xff1f; 在开始之前&#xff0c;让我们先明确一下为什么选择一对一直播美颜SDK是一个明智的决定。…

WorkPlus即时通讯app打通业务与生态,实现高效管理与协同

作为移动应用管理领域的领先品牌&#xff0c;WorkPlus通过其创新性的解决方案&#xff0c;成为企业级应用管理平台中的佼佼者。WorkPlus的使命是连接业务和生态&#xff0c;为企业提供一体化的移动应用管理解决方案&#xff0c;从而助力企业实现数字化转型和有效的业务运营。 …

PTE阶段规划

目录 复习的各个阶段 线下应该如何 rs应对 从来都是流利度大于内容 推荐的练习网站 口语 DI 关键词是不能念错 口语 RL rl每日练习方法 ASQ 写作 swt 阅读 一半靠机经 听力 口语和听力 考模版来熟悉 熟悉模版 强调的是&#xff0c;整个的逻辑思维 字字和句句都…

OpenAI举办“ChatGPT应用开发大赛”:226个团队参加,异常火热!

韩国先驱报消息&#xff0c;OpenAI与全球最大电信公司之一SKT在首尔圆满举办&#xff0c;生成式AI开发者大赛“Prompter DaySeoul 2023”。主要通过ChatGPT等大模型&#xff0c;开发造福社会的生成式AI应用。 本次大赛受到热烈欢迎共有226个团队参加&#xff0c;奖金共计1亿韩…

蓝桥等考Python组别十六级002

第一部分:选择题 1、Python L16 (15分) a和b是两个集合,它们的关系如下图所示: 以下哪个表达式的值是True?( ) a > ba < ba == ba >= b正确答案:B 2、Python

Git 学习笔记 | Git 项目创建及克隆

Git 学习笔记 | Git 项目创建及克隆 Git 学习笔记 | Git 项目创建及克隆创建工作目录与常用指令本地仓库搭建克隆远程仓库 Git 学习笔记 | Git 项目创建及克隆 创建工作目录与常用指令 工作目录&#xff08;WorkSpace)一般就是你希望Git帮助你管理的文件夹&#xff0c;可以是…

SSO单点登录和OAuth2.0区别

一、概述 SSO是Single Sign On的缩写&#xff0c;OAuth是Open Authority的缩写&#xff0c;这两者都是使用令牌的方式来代替用户密码访问应用。流程上来说他们非常相似&#xff0c;但概念上又十分不同。SSO大家应该比较熟悉&#xff0c;它将登录认证和业务系统分离&#xff0c…

OpenCV实现单目相机检测物体尺寸

目录 步骤&#xff1a; Canny边缘检测算法介绍&#xff1a; 多边形逼近 代码实现&#xff1a; 效果展示&#xff1a; 步骤&#xff1a; 导入必要的库&#xff1a;cv2用于图像处理&#xff0c;numpy用于数组操作。定义了一个函数preprocess&#xff0c;用于对图像进行预处理…

在OpenWRT上自动重拨号获取公网IP(手记)

在OpenWRT上自动重拨号获取公网IP&#xff08;手记&#xff09; 前言 哈喽&#xff0c;大家是否有过这样的经历&#xff1a;想在家里搭建一个小型的服务器、或者是一个NAS&#xff0c;但由于运营商提供的IP地址是一个内网地址&#xff0c;但有一定的概率能获得公网IP。这篇文…

牙齿矫正后需要戴保持器有哪几种?

牙齿矫正后需要戴保持器有哪几种&#xff1f; 矫正牙齿一般是采取通过牙套产生的力量&#xff0c;能够使牙齿回归到正常的牙列当中&#xff0c;在矫正牙齿之后&#xff0c;就需要适当的佩戴保持器&#xff0c;能够起到固定牙齿的效果&#xff0c;目前临床上常见的保持器有两大…

COS流量被盗刷了

背景 家人们谁懂啊&#xff0c;早上起来发了日常的文章&#xff0c;出门的时候发现手机上腾讯云给的提示&#xff1a;COS欠费了。我不敢相信的我的眼睛&#xff01;我之前每个月才花费几毛钱的&#xff0c;知道的伙伴都知道我这可是卖废品攒下来的钱&#xff01;敢看了一下账单…

超高频RFID模具精细化生产管理方案

近二十年来&#xff0c;我国的模具行业经历了快速发展的阶段&#xff0c;然而&#xff0c;模具行业作为一个传统、复杂且竞争激烈的行业&#xff0c;企业往往以订单为导向&#xff0c;每个订单都需要进行新产品的开发&#xff0c;从客户需求分析、结构确定、报价、设计、物料准…

湖南互联网医院|湖南互联网医院牌照办理流程及材料

互联网医牌照&#xff0c;一个让医疗行业焕发数字化新生的通行证。随着时代的进步和技术的发展&#xff0c;互联网已经深入各个行业&#xff0c;医疗领域也不例外。而互联网医牌照的办理流程、内容以及所需材料&#xff0c;则是诸多医疗机构所关注的核心内容。 第一种是实体医…

centos7终端无图形界面安装tbb

1、官网下载tbb&#xff1a; https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#onetbb 2、终端执行&#xff1a; ./l_tbb_oneapi_p_2021.10.0.49543_offline.sh -a --cli3、cd /opt/intel/oneapi 4、source setvars.sh …

一文搞懂二叉树中序遍历的三种方法

系列文章&#xff1a; 相关题目&#xff1a; 94. 二叉树的中序遍历 中序遍历结果为&#xff1a;4 2 5 1 6 3 7 总体上分为两种框架&#xff0c;递归框架和非递归框架&#xff0c;递归框架又分为两种思路&#xff1a;分解思路和遍历思路。 递归 1、分解思路 【分解为子问题】…