堆排序总结

2023-05-16

本文内容来源于《漫画算法》和数据结构教材
这里提到的堆是一个二叉堆,本质上是一颗完全二叉树。堆排序只需要一个记录大小的辅助空间。
1.java实现

	/**
	 * 下沉调整
	 * @param arr 待调整的堆
	 * @param parentIndex 要下沉的父节点下标
	 * @param length 堆的有效大小(一般指存储堆的数组长度)
	 */
	void downAdjust(int[] arr, int parentIndex, int length) {
		// temp保存父节点的值,用于最后的赋值
		int temp = arr[parentIndex];
		int childIndex = 2 * parentIndex + 1;
		while (childIndex < length) {
			// 如果有rightChild,并且rightChild值大于leftChild值,则childIndex指向rightChild
			if (childIndex + 1 < length && arr[childIndex + 1] > arr[childIndex]) {
				childIndex++;
			}

			// 如果父节点大于子节点中的最大元素,则跳出循环,因为无需下沉
			if (temp >= arr[childIndex])
				break;

			//
			arr[parentIndex] = arr[childIndex];
			parentIndex = childIndex;
			childIndex = 2 * childIndex + 1;
		}
		arr[parentIndex] = temp;
	}
	
	/**
	 * 堆排序(升序)
	 * @param arr 待调整的堆
	 */
	void heapSort(int[] arr) {
		// 1.把无序数组构建成最大堆[从最后一个非叶子节点,逐个向前进行下沉调整]
		for (int i = (arr.length - 2) / 2; i >= 0; i--) {
			downAdjust(arr, i, arr.length);
		}
		System.out.println(Arrays.toString(arr));
		// 2.循环删除(并非真正意义的删除,只是移动到最后)堆顶元素,移到集合尾部,调整堆产生新的堆顶
		for (int i = arr.length - 1; i > 0; i--) {
			// 最后一个元素和第一个元素进行交换
			int temp = arr[i];
			arr[i] = arr[0];
			arr[0] = temp;
			// 下沉调整
			downAdjust(arr, 0, i);
		}
	}
	
	@Test
	public void fun1() {
		int[] arr = new int[] { 1, 3, 2, 6, 5, 7, 8, 9, 10, 0 };
		heapSort(arr);
		System.out.println(Arrays.toString(arr));
	}

2.C语言实现

/*
* 堆排序的实现
* 数据结构(C语言版本) 严蔚敏 吴伟民 
* 
  实现堆排序需要解决2个问题:
  (1)如何由一个无序序列建成一个堆?
  (2)如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
*/
#include<iostream>
using namespace std;

/*
堆的调整
s 根节点索引
m 数组有效长度

调整为大顶堆
*/
void HeapAdjust(int arr[], int s, int m) {
	//cout<<"m"<<m<<endl;
	// 保存需要调整的节点
	int temp = arr[s];

	for (int j = 2 * s + 1; j <= m; j = 2 * j + 1) { // 沿key较大的孩子节点向下筛选
		/*
		 cout<<"parent "<<arr[s]<<endl;
		 cout<<"left "<<arr[j]<<endl;
		 if(j+1<=m)
		 cout<<"right "<<arr[j+1]<<endl;
		 else
		 cout<<"right"<<" is empty"<<endl;
		 cout<<"+"<<j<<endl;
		 */
		if (j < m && arr[j] < arr[j + 1]) // j为key较大的记录的下标
			++j;
		//cout<<"="<<j<<endl;
		if (temp > arr[j]) {
			//cout<<temp<<"gt"<<arr[j]<<" end for loop"<<endl;
			break;
		}
		arr[s] = arr[j]; // 较大的节点"上浮"
		/* 
		 这里省略了arr[j]=temp;这一步多余了,
		 只需要在最后执行这一步,将最初的s指向的元素放到最终位置即可
		 */
		arr[j] = temp; //(1)可以在调试的时候加上这句话,方便查看最终结果
		s = j; // 父节点索引指向刚调整的j位置
	}
	arr[s] = temp; //如果循环没有发生数据交换,这一步就没必要啦,有也不会错。
	//cout<<"**********************"<<endl;
}

void HeapSort(int arr[]) {
	// 1.构建堆(这个堆是一个二叉堆,本质是一颗完全二叉树)
	int len = 8;
	for (int i = len / 2 - 1; i >= 0; --i) {
		HeapAdjust(arr, i, len - 1);
	}
	cout << "-------------------------" << endl;
	// 2.调整剩余元素成为一个新的堆
	for (int i = len - 1; i > 0; --i) {
		// 堆顶元素和当前未经排序子序列arr[0..i]中最后一个记录相互交换
		int temp = arr[0];
		arr[0] = arr[i];
		arr[i] = temp;

		HeapAdjust(arr, 0, i - 1); // 将arr[0..i-1]重新调整为大顶堆
	}

}

int main(int argc, char* argv[]) {
	int arr[] = { 49, 38, 65, 97, 76, 13, 27, 49 };
	HeapSort(arr);

	int len = 8;
	for (int i = 0; i < len; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
	return 0;
}

堆排序的练习java版[漫画算法]
堆本质上是一颗完全二叉树,用数组存储,
parent,leftChild,rightChild
他们之间的数组下标的关系如下:
{ l e f t C h i l d = 2 ∗ p a r e n t + 1 ; r i g h t C h i l d = 2 ∗ p a r e n t + 2 ; \begin{cases}leftChild=2*parent+1;\\ rightChild=2*parent+2;\end{cases} {leftChild=2parent+1;rightChild=2parent+2;


堆排序算法步骤
1.把无序数组构建成二叉堆。
2.循环删除堆顶元素,并将该元素移到集合尾部,调整堆产生新的堆顶。
(这里的删除并非真的删除只是移动到了数组的后面相应的位置上)

时间复杂度O(nlogn)
空间复杂度O(1)


从宏观上看堆排序和快速排序的异同
相同点,1.堆排序和快速排序的平均时间复杂度都是O(nlogn),并且都是不稳定排序。
不同点,1.快速排序的最坏时间复杂度是O(n^2);而堆排序的最坏时间复杂度稳定在O(nlogn)
2.此外快排的递归和非递归方式的空间复杂度都是O(logn),
而堆排序的空间复杂度是O(1)

在漫画算法里面,有许多的堆调整的示意图,非常有助于理解。


堆的定义如下:n个元素的序列 { k 1 , k 2 , . . . , k n , } \lbrace k_{1},k_{2},...,k_{n}, \rbrace {k1,k2,...,kn,}当且仅当满足如下关系时,称之为堆。这里教材定义的下标是从1开始的,实际程序的下标是从0开始的,注意转换
{ k i ⩽ k 2 i k i ⩽ k 2 i + 1 \begin{cases} k_{i} \leqslant k_{2i}\\ k_{i} \leqslant k_{2i+1} \end{cases} {kik2ikik2i+1 { k i ⩾ k 2 i k i ⩾ k 2 i + 1 \begin{cases} k_{i} \geqslant k_{2i}\\ k_{i} \geqslant k_{2i+1} \end{cases} {kik2ikik2i+1
( i = 1 , 2 , . . . , ⌊ n 2 ⌋ ) (i=1,2,...,\lfloor \frac{n}{2} \rfloor) (i=1,2,...,2n)
若将和此序列对应的一维数组(即以一维数组做此序列的存储结构)看成是一个完全二叉树,则堆的含义表名,完全二叉树中所有非终端节点的值均不大于(或不小于)其左右孩子节点的值。由此,若序列 { k 1 , k 2 , . . . , k n , } \lbrace k_{1},k_{2},...,k_{n}, \rbrace {k1,k2,...,kn,}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。
漫画算法里面的定义还是比较浅显易懂的。教材定义太复杂和吓人。

2种堆

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

堆排序总结 的相关文章

  • redisson 布隆过滤器(校验唯一性)

    一 需求背景 项目中需要保证订单号唯一性 xff0c 保证准确率和速度的前提下 xff0c 可以使用redis的redisson布隆过滤器来实现 缺点 xff1a 存在误判率 使用时跟产品经理确认是否允许出现误判的情况 二 实战代码 1 开
  • 笑谈Android图表------MPAndroidChart

    MPAndroidChart是一款基于Android的开源图表库 xff0c MPAndroidChart不仅可以在Android设备上绘制各种统计图表 xff0c 而且可以对图表进行拖动和缩放操作 xff0c 应用起来非常灵活 MPAnd
  • 详谈高大上的图片加载框架Glide -应用篇

    在Android设备上 xff0c 加载网络图片一直是一个头疼的问题 xff0c 因为Android设备种类繁多 xff08 当然最主要的是配置 xff09 xff0c 处理的稍不周到轻则应用卡顿 xff0c 严重者就会出现OOM的 xff
  • 微信小程序开发环境搭建

    微信小程序可谓是今天最火的一个名词了 xff0c 一经出现真是轰炸了整个开发人员 xff0c 当然很多App开发人员有了一个担心 xff0c 微信小程序的到来会不会给移动端App带来一个寒冬 xff0c 身为一个Android开发者我是不相
  • 实现APP定位功能

    源码传送门 若你不小心点击进入GitHub了捎带给个star 前言 最近更新项目中用的百度定位SDK时遇见了一个奇葩的问题 当升级SDK后百度定位一直返回505 通过百度定位官网查看该码表示AK非法或者不存在 很纠结 于是自己又写了一个de
  • Java利器之UML类图详解

    前言 UML xff08 Unified Modeling Language xff09 中文统一建模语言 xff0c 是一种开放的方法 xff0c 用于说明 可视化 构建和编写一个正在开发的 面向对象的 软件密集系统的制品的开放方法 UM
  • 从零开始学习Linux部署Java web项目

    前言 最近越来越发现需要学习的东西太多了 xff0c 前几天公司服务器出现问题 xff0c 需要对服务器硬件进行维护 xff0c 当然服务器上的服务需要部署到另一个服务器上 这对于我来说是很陌生的 xff0c 虽然这件工作没有让我去做 xf
  • 微信小程序分页加载

    分页加载功能大家遇到的应该会经常遇到 xff0c 应用场景也很多 xff0c 例如微博 xff0c QQ xff0c 微信朋友圈以及新闻类应用 xff0c 都会有分页加载的功能 xff0c 这不仅节省了我们用户的流量 xff0c 还提升了用
  • ReactNative ViewPageAndroid组件详解

    源码传送门 在我们开发Android的时候 xff0c ViewPage这个控件的使用频率还是很高的 xff0c 最简单的就是制作引导页 xff0c 应用程序的主界面等 xff0c 在ReactNative开发中实现该功能的组件是ViewP
  • Android自定义数字键盘

    好久没有写Android的文章了 xff0c 有两三个月多了吧 xff0c 刚开始搞微信小程序 xff0c 后来又开搞ReactNative 现在又兴奋的开搞AI机器学习的东西 xff0c 感觉挺有意思的 xff0c 不过AI与其它的东西相
  • ConstraintLayout基础介绍

    自去年Google I O 大会发布ConstraintLayout至今 xff0c 已有一年多的时间 xff0c 但是并没有普及开来 xff0c 了解过ConstraintLayout布局的人知道 xff0c 它的性能的确提升了不少 在前
  • Gson转换报错com.google.gson.JsonSyntaxException

    转载请标明出处 xff1a http blog csdn net xiejinquan article details 52002196 Gson将jsonobject的字符转化为Bean类或者将jsonarray的字符串转化为List l
  • MTK6580调试IMX132流程分析

    MTK6580调试IMX132流程分析 一开始不了解 MTK 的点亮流程 怎么办呢 1 MTK 开机是 首先是 CameraService 先起来 然后就通过获取 HAL 中的 sensorList 中的信息 CameraManager与C
  • 双线性插值算法

    图像的缩放很好理解 就是图像的放大和缩小 传统的绘画工具中 有一种叫做 放大尺 的绘画工具 xff0c 画家常用它来放大图画 当然 xff0c 在计算机上 xff0c 我们不再需要用放大尺去放大或缩小图像了 xff0c 把这个工作交给程序来
  • JAVA字符串判空的方法

    1 记录自己工作中的问题 xff1a 针对某些字符串进行判空时 xff0c 出现的BUG StringUtils hasText StringUtils hasText null 61 false StringUtils hasText 3
  • 出现次数最多的小写字母

    出现次数最多的小写字母 题目描述 输入一个由小写字母组成的字符串 xff08 字符数量 lt 61 100 xff09 xff0c 输出出现次数最多的小写字母 注意 xff1a 如果有多个小写字母出现的次数一样多 xff0c 则输出ASCI
  • EFCore 从入门到精通-6(详谈查询)

    目录 1 初始准备1 1 工具准备1 2 程序准备1 3 准备数据 2 基础回顾以及探寻2 1 单个查询2 2 查询所有的数据 2 3 筛选和过滤查询2 4 探究原理 3 客户端评估和服务端评估3 1 IEnumerable And IQu
  • 【Android解决方案】在onResume里调用getIntent()得到的是上一次数据

    我有四个媒体分类 xff08 Record xff0c Music xff0c Video xff0c Picture xff09 xff0c 里面除了数据不同 xff0c 界面都是相似的 xff0c 所以我把它们用一个MediaActiv
  • pycharm运行停止快捷键

    运行 shift 43 f10 停止 ctrl 43 f2
  • RecyclerView预加载

    private boolean isLoadingMore 61 false 是否预加载 recyclerView addOnScrollListener new RecyclerView OnScrollListener 64 Overr

随机推荐

  • 自定义右侧弹出dialog并填充状态栏

    DialogUtil xff1a public class DialogUtil private Dialog dialog private View inflate public void showRightDialog Context
  • Android监听横竖屏切换

    偶然在项目中用到播放视频时 xff0c 需要横屏将视频全屏播放 xff0c 所以需要监听屏幕的横竖屏切换事件 ConfigChanges xff0c 用于捕获手机状态的改变 xff0c 当横竖屏切换 xff0c 屏幕尺寸变化 xff0c 弹
  • SVN利用 AS 进行代码对比的方法

    第 1 种 xff1a 如果我们是从 SVN 检出的项目 xff0c 并且想比较本地代码与从 SVN 检出时的代码相比都有那些区别 xff0c 可以按如下步骤操作 如上图所示 xff0c 在代码编辑区 xff0c 右键唤出功能菜单 xff0
  • ADB操作命令详解大全

    ADB 操作命令详解及用法大全 Lucas liu的博客 CSDN博客
  • Android Studio build下面找不见assembleDebug选项解决办法

    在开发Android的AAR库时 xff0c 习惯点击右侧gradle面板的Task任务进行编译 xff0c 如选择assembleDebug或assembleRelease进行编译 xff0c 如下 xff1a 说明 xff1a 其中as
  • android 注销到登陆界面实现

    code class java span class hljs keyword public span span class hljs class span class hljs keyword class span span class
  • 中兴2016校招软件在线笔试题

    面试经验可以参考我的另一篇文章 xff0c 是7月初参加openday面试的 xff0c 文章链接http blog csdn net dandelion1314 article details 47009585 招聘群里有人发的招聘时间安
  • 设置AndroidStudio左侧和右侧的字体

    1 File Settings Appearance amp Behavior Appearance xff0c 右边Override default fonts by not recommended 2 设置代码大小 xff1a File
  • Android下载网络资源文件

    直接上代码 xff1a lt uses permission android name 61 34 android permission WRITE EXTERNAL STORAGE 34 gt lt uses permission and
  • 出现:trying to draw too large(138078000bytes) bitmap:错误时

    这里就不翻译了 xff0c 意思就是说你将高分辨率图片放在了低分辨率文件夹下 例如 xff1a 图片的分辨率是属于xxhdpi的 xff0c 而你将这张图片放在了drawable xhdpi或者比这个还低的文件夹下 xff0c 就会报这个错
  • Android把图片压缩到一定大小并不失真

    本文转载只供参考 一 图片压缩方式 图片按比例大小压缩方法 64 param srcPath xff08 根据路径获取图片并压缩 xff09 64 return public static Bitmap getimage String sr
  • Android 动态设置TextView的位置

    RelativeLayout LayoutParams layoutParams 61 new RelativeLayout LayoutParams 40 40 宽高 layoutParams setMargins int dstX 20
  • 神经网络应用较多的算法,图卷积神经网络应用

    神经网络原理及应用 神经网络原理及应用1 什么是神经网络 xff1f 神经网络是一种模拟动物神经网络行为特征 xff0c 进行分布式并行信息处理的算法 这种网络依靠系统的复杂程度 xff0c 通过调整内部大量节点之间相互连接的关系 xff0
  • Java泛型学习

    纯属个人理解 xff0c 代码参考自视频 用途 xff1a 1 用于集合容器中 xff0c 可以使集合记住存储数据的类型 xff0c 防止频繁转换类型可能导致的ClassCastException 用于javac编译器的类型检查 xff0c
  • Java反射学习

    文字和代码来源于视频 反射 xff0c 通过它我们可以得到一个Java类的全部信息 xff0c 可以调用类的普通方法 xff0c 构造方法 xff0c 对类进行实例化 xff0c 操作类的属性 类中的所有内容 xff1a 属性 构造方法 普
  • 面试题之反转单向链表

    题目为 xff1a 将一个单向链表反转 xff0c 写出算法步骤或代码 懵批了 今学习如下 xff0c 文章代码参考https blog csdn net K346K346 article details 93371829 xff0c 感谢
  • 冒泡排序总结

    本文内容和代码均来自于 漫画算法 xff0c 小灰和大黄的对话 xff0c 非常有趣味的一本书 现理论结合实践 xff0c 做一下测试 span class token keyword private span span class tok
  • net6的Web MVC项目实现限流功能

    原理 xff1a 利用MemoryCache服务组件 xff0c 记录用户最后一次访问接口的时间 xff0c 如果本次访问距离最后一次访问不超过1秒 xff0c 提示用户访问过于频繁 xff0c 否则 xff0c 接口可以正常访问 然后利用
  • 快速排序总结

    文章内容和代码来自 漫画算法 和数据结构教材 现进行一下代码编写练习 1 双边循环法 span class token comment 双边循环法 xff0c 从左右两端分别向中间进行比较和交换数据 递归实现 span span class
  • 堆排序总结

    本文内容来源于 漫画算法 和数据结构教材 这里提到的堆是一个二叉堆 xff0c 本质上是一颗完全二叉树 堆排序只需要一个记录大小的辅助空间 1 java实现 span class token comment 下沉调整 64 param ar