堆排序——我欲修仙(功法篇)

news/2024/11/8 21:04:42/

个人主页:【😊个人主页】
系列专栏:【❤️我欲修仙】
学习名言:学习和研究好比爬梯子,要一步一步地往上爬,企图一脚跨上四五步,平地登天,那就必须会摔跤了。——华罗庚


在这里插入图片描述


系列文章目录

第一章 ❤️ 学习前的必知知识
第二章 ❤️ 二分查找


文章目录

  • 系列文章目录
  • 前言🚗🚗🚗
  • 罗伯特·弗洛伊德
  • 堆排序
  • 堆排序原理
  • 代码实现(C语言)


前言🚗🚗🚗

在数据结构与算法的世界里,有六种常见的排序算法,在之前的故事中我们了解了其中的三种最为基础的算法,今天我们要接触道的可能是六种算法中最难理解的——堆排序

罗伯特·弗洛伊德

计算机科学家,图灵奖得主,前后断言法的创始人,堆排序算法和Floyd-Warshall算法的创始人之一。

弗洛伊德和威廉姆斯(J.Williams)在1964年共同发明了著名的堆排序算法HEAPSORT
这是与英国学者霍尔 (C.A.R.Hoare,1980年图灵奖获得者)发明的QUICKSORT齐名的高效排序算法之一。此外还有直接以弗洛伊德命名的求最短路的算法,这是弗洛伊德利用动态规划(dynamic programming)的原理设计的一个高效算法。

堆排序

==堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。==堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序的本质是利用了数据结构中的堆

在这里插入图片描述

堆排序原理

  • 大顶堆:每个节点的值都大于或者等于它的左右子节点的值。
  • 小顶堆:每个节点的值都小于或者等于它的左右子节点的值。
  • 对于大顶堆:arr[i] >= arr[2i + 1] && arr[i] >= arr[2i + 2]
  • 对于小顶堆:arr[i] <= arr[2i + 1] && arr[i] <= arr[2i + 2]

在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。
堆中定义以下几种操作:

  • 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
  • 创建最大堆(Build Max Heap):将堆中的所有数据重新排序
  • 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

堆排序的基本思路就是:将带排序的序列构造成一个大顶堆,根据大顶堆的性质,当前堆的根节点(堆顶)就是序列中最大的元素;2、将堆顶元素和最后一个元素交换,然后将剩下的节点重新构造成一个大顶堆;3、重复步骤2,如此反复,从第一次构建大顶堆开始,每一次构建,我们都能获得一个序列的最大值,然后把它放到大顶堆的尾部。最后,就得到一个有序的序列了。

在这里插入图片描述

代码实现(C语言)

#include <stdio.h>
#include <stdlib.h>void swap(int* a, int* b)
{int temp = *b;*b = *a;*a = temp;
}void max_heapify(int arr[], int start, int end) 
{//建立父节点指标和子节点指标int dad = start;int son = dad * 2 + 1;while (son <= end)  //若子节点指标在范围内才做比较{if (son + 1 <= end && arr[son] < arr[son + 1]) //先比较两个子节点大小,选择最大的son++;if (arr[dad] > arr[son]) //如果父节点大於子节点代表调整完毕,直接跳出函数return;else  //否则交换父子内容再继续子节点和孙节点比较{swap(&arr[dad], &arr[son]);dad = son;son = dad * 2 + 1;}}
}void heap_sort(int arr[], int len) 
{int i;//初始化,i从最後一个父节点开始调整for (i = len / 2 - 1; i >= 0; i--)max_heapify(arr, i, len - 1);//先将第一个元素和已排好元素前一位做交换,再重新调整,直到排序完毕for (i = len - 1; i > 0; i--) {swap(&arr[0], &arr[i]);max_heapify(arr, 0, i - 1);}
}int main() {int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };int len = (int) sizeof(arr) / sizeof(*arr);heap_sort(arr, len);int i;for (i = 0; i < len; i++)printf("%d ", arr[i]);printf("\n");return 0;
}

在这里插入图片描述


http://www.ppmy.cn/news/85166.html

相关文章

Python——openpyxl读取Excel表格(读取、单元格修改、单元格加底色)

首先python读取Excel的库有很多&#xff0c;包括xlwings&#xff0c;pandas&#xff0c;xlrd等等&#xff0c;我比较常用的是openpyxl&#xff0c;以及pandas&#xff0c;当然还有喜欢将数据量比较大的Excel转为csv格式再读取。 今天我们用openpyxl来读取excel文件&#xff0c…

弘博创新2023读书会|“读”赢成长,“书”立未来

读万卷书&#xff0c;行万里路&#xff0c;以书会友&#xff0c;提升自我。 为了让大家在繁忙的工作中抽时间静下心来读书&#xff0c;与志同道合的人交流和分享自己的想法&#xff0c;弘博创新于5月21日举办了线下读书会活动&#xff0c;学友们都积极参加本次读书会。 参加读书…

CentOS7编译安装Python3.10(含OpenSSL1.1.1安装),创建虚拟环境,运行Django项目(含sqlite版本报错)

文章目录 1、CentOS安装OpenSSL1.1.1&#xff08;前置环境&#xff09;2、CentOS安装 Python 3.103、创建虚拟环境4、运行Django项目 1、CentOS安装OpenSSL1.1.1&#xff08;前置环境&#xff09; 编译安装Python3.10时需要openssl1.1.1 查看当前版本 & 删除openssl1.0 …

无毛刺时钟切换电路

为了SOC设计的低功耗性&#xff0c;多时钟域的划分是常用手段之一&#xff0c;有两个时钟&#xff0c;A为50Mhz&#xff0c;B为100Mhz&#xff0c;请设计无毛刺时钟切换电路&#xff0c;根据控制信号control&#xff0c;输出所需时钟信号。 control信号至少对一个时钟信号为异…

单目相机通过图像分析方式如何计算物体上下运动距离地面的高度?

要通过固定安装的摄像头计算物体上下运动距离地面的高度&#xff0c;可以采用计算机视觉和图像处理技术。以下是一个详细的步骤说明&#xff1a; 1. **摄像头准备和安装**&#xff1a;首先&#xff0c;确保摄像头已经正确安装&#xff0c;并能捕获到物体的上下运动。为了获得更…

conda环境安装使用教程

conda&#xff0c;anaconda&#xff0c;miniconda傻傻分得清楚 Conda是一个开源的包管理系统和环境管理系统&#xff0c;可以用于安装、管理和卸载软件包以及创建和管理虚拟环境。Anaconda是一个基于Python的数据科学平台&#xff0c;包括Python解释器、Conda包管理器、Jupyte…

azkaban使用了解

https://github.com/azkaban/azkaban/tags https://codeload.github.com/azkaban/azkaban/tar.gz/refs/tags/3.84.4 Azkaban是一套简单的任务调度服务&#xff0c;整体包括三部分webserver、dbserver、executorserver。Azkaban 为 LinkedIn 开源的分布式工作流调度框架&#…

(IDEA)springCloud项目导入本地jar包方法和项目打包时找不到引入本地jar包的问题解决方案

idea导入本地jar包 方法一:点击左上角File–>Project Structure–>Modules。打开Modules界面点击下方号&#xff0c;选择第一项&#xff0c;找到想要导入的本地jar包。此方法可以使项目使用导入的jar包程序不报错&#xff0c;但是在打包项目时&#xff0c;会出现找不到程…