堆排序

本文详细介绍了堆排序算法的工作原理,包括如何构建大根堆并利用它来进行非降序排序。通过具体的示例和代码展示了堆排序的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

堆排序(Heapsort)

          堆分为大根堆和小根堆,是完全二叉树大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,根据大根堆的要求可知,最大的值一定在堆顶。

堆排序步骤示例

(1)、建堆: 建堆的核心内容是调整堆,使二叉树满足堆的定义(每个节点的值都不大于其父节点的值)。调堆的过程应该从最后一个非叶子节点开始,假设有数组A = {1, 3, 4, 5, 7, 2, 6, 8, 0}。那么调堆的过程如下图,数组下标从0开始,A[3] = 5开始。分别与左孩子和右孩子比较大小,如果A[3]最大,则不用调整,否则和孩子中的值最大的一个交换位置,在图1中因为A[7] > A[3] > A[8],所以A[3]与A[7]对换,从图1转到图2。

(2)、调堆:如果初始数组是非降序排序,不需要调堆,本身满足堆的定义,运行时间为O(1),为最好情况;如果初始数组是如图5,只有A[0] = 1不满足堆的定义,经过与子节点的比较调整到图6,但是图6仍然不满足堆的定义,所以要递归调整,一直到满足堆的定义或者到堆底为止。如果递归调堆到堆底才结束,那么是最坏情况,运行时间为O(h) (h为需要调整的节点的高度,堆底高度为0,堆顶高度为floor(logn) )。建堆完成之后,堆如图7是个大根堆。将A[0] = 8 与 A[heapLen-1]交换,然后heapLen减一,如图8,然后AdjustHeap(A, heapLen-1, 0),如图9。如此交换堆的第一个元素和堆的最后一个元素,然后堆的大小heapLen减一,对堆的大小为heapLen的堆进行调堆,如此循环,直到heapLen == 1时停止,最后得出结果如图12。


注:子节点在数组中的下标与父节点的在数组中的下标之间的关系

堆排序示例代码

/**
 *  堆排序
 * @author bianjie
 *
 */
public class Heapsort {

	/**
	 * 建堆
	 * 
	 * @param data
	 *            数据
	 * @param length
	 *            数据长度
	 */
	public static void buildHeap(int data[], int length) {

		// 起始的第一个父节点
		int startIndex = length / 2 - 1;
		for (; startIndex >= 0; startIndex--) {
			// 调堆
			adjustHeap(data, length ,startIndex);
		}
	}

	/**
	 * 调整堆的大小位置
	 * @param data 数据数组
	 * @param dataLength 数据长度
	 * @param parentIndex 父节点,需注意父节点与子节点的关系得到的下标
	 */
	public static void adjustHeap(int data[], int dataLength, int parentIndex) {
		//因为数组的首个下标为0,而堆中对应的节点比起大1,所以计算左右子节点的时候需注意
		//不能直接用2*parentIndex和(2*parentIndex+1)作为左右节点在数组中的下标
		//当然你也可以一开始就调节他们之间下标一一对应关系,就可以用
		// 子左节点下标
		int leftChildIndex = 2 * (parentIndex + 1) - 1;
		// 子右节点下标
		int rightChildIndex = 2 *(parentIndex + 1);
		// 节点中的最大值的下标,初始设置为父节点为最大值
		int maxValueIndex = parentIndex;
		while (leftChildIndex <= dataLength || rightChildIndex <= dataLength) {
			// 左节点存在且大于父节点
			if (leftChildIndex < dataLength && data[leftChildIndex] > data[maxValueIndex]) {
				maxValueIndex = leftChildIndex;
			}
			// 右节点存在且大于父节点
			if (rightChildIndex < dataLength &&  data[rightChildIndex] > data[maxValueIndex]) {
				maxValueIndex = rightChildIndex;
			}
			// 存在子节点的值比父节点的值大,交换两者的值
			if (maxValueIndex != parentIndex) {
				// 进行数据位置交换
				swapData(data, parentIndex, maxValueIndex);
				// 打印数据
				printData(data);
				adjustHeap(data,dataLength,parentIndex);
				// 打乱了事先的低端排序,需要重新进行检验是否满足堆排序
				parentIndex = maxValueIndex;
				leftChildIndex =  2 * (parentIndex + 1) - 1;
				rightChildIndex = 2 * (parentIndex + 1);
			}else{
				break;
			}
		}
	}

	/**
	 * 排序
	 * @param data 数据数组
	 */
	public static void sortHeap(int data[]) {
		int dataLength = data.length;
		// 建堆
		buildHeap(data, dataLength);
		//辅助显示排序的结果标志
		int time = 1;
		while (dataLength > 1) {
			//一趟排序完得到的堆顶的最大值进行首尾位置调换,
			//同时将数据长度减一,起到保存已经得到的最大值的数据数列位置
			swapData(data, 0, --dataLength);
			printData(data);
			System.out.println("------ 第   "+(time++)+" 趟排序完成---");
			//重新进行建堆,调堆
			buildHeap(data, dataLength);
		}
	}

	/**
	 * 打印数据
	 * 
	 * @param data
	 */
	public static void printData(int data[]) {
		for (int i : data) {
			System.out.print(i + " ");
		}
		System.out.println();
	}

	
	/**
	 * 交换数据
	 * 
	 * @param data 数据数组
	 * @param firstIndex 要交换的第一个数据下标
	 * @param secondIndex 要交换的第二个数据下标
	 */
	public static void swapData(int[] data, int firstIndex, int secondIndex) {
		int temp = data[firstIndex];
		data[firstIndex] = data[secondIndex];
		data[secondIndex] = temp;
	}

	
	public static void main(String[] args) {
		int data[] = { 1, 3, 4, 5, 7, 2, 6, 8, 0 };
		printData(data);
		sortHeap(data);

	}

}


运行结果


标题基于SpringBoot+Vue的学生交流互助平台研究AI更换标题第1章引言介绍学生交流互助平台的研究背景、意义、现状、方法与创新点。1.1研究背景与意义分析学生交流互助平台在当前教育环境下的需求及其重要性。1.2国内外研究现状综述国内外在学生交流互助平台方面的研究进展与实践应用。1.3研究方法与创新点概述本研究采用的方法论、技术路线及预期的创新成果。第2章相关理论阐述SpringBoot与Vue框架的理论基础及在学生交流互助平台中的应用。2.1SpringBoot框架概述介绍SpringBoot框架的核心思想、特点及优势。2.2Vue框架概述阐述Vue框架的基本原理、组件化开发思想及与前端的交互机制。2.3SpringBoot与Vue的整合应用探讨SpringBoot与Vue在学生交流互助平台中的整合方式及优势。第3章平台需求分析深入分析学生交流互助平台的功能需求、非功能需求及用户体验要求。3.1功能需求分析详细阐述平台的各项功能需求,如用户管理、信息交流、互助学习等。3.2非功能需求分析对平台的性能、安全性、可扩展性等非功能需求进行分析。3.3用户体验要求从用户角度出发,提出平台在易用性、美观性等方面的要求。第4章平台设计与实现具体描述学生交流互助平台的架构设计、功能实现及前后端交互细节。4.1平台架构设计给出平台的整体架构设计,包括前后端分离、微服务架构等思想的应用。4.2功能模块实现详细阐述各个功能模块的实现过程,如用户登录注册、信息发布与查看、在线交流等。4.3前后端交互细节介绍前后端数据交互的方式、接口设计及数据传输过程中的安全问题。第5章平台测试与优化对平台进行全面的测试,发现并解决潜在问题,同时进行优化以提高性能。5.1测试环境与方案介绍测试环境的搭建及所采用的测试方案,包括单元测试、集成测试等。5.2测试结果分析对测试结果进行详细分析,找出问题的根源并
内容概要:本文详细介绍了一个基于灰狼优化算法(GWO)优化的卷积双向长短期记忆神经网络(CNN-BiLSTM)融合注意力机制的多变量多步时间序列预测项目。该项目旨在解决传统时序预测方法难以捕捉非线性、复杂时序依赖关系的问题,通过融合CNN的空间特征提取、BiLSTM的时序建模能力及注意力机制的动态权重调节能力,实现对多变量多步时间序列的精准预测。项目不仅涵盖了数据预处理、模型构建与训练、性能评估,还包括了GUI界面的设计与实现。此外,文章还讨论了模型的部署、应用领域及其未来改进方向。 适合人群:具备一定编程基础,特别是对深度学习、时间序列预测及优化算法有一定了解的研发人员和数据科学家。 使用场景及目标:①用于智能电网负荷预测、金融市场多资产价格预测、环境气象多参数预报、智能制造设备状态监测与预测维护、交通流量预测与智慧交通管理、医疗健康多指标预测等领域;②提升多变量多步时间序列预测精度,优化资源调度和风险管控;③实现自动化超参数优化,降低人工调参成本,提高模型训练效率;④增强模型对复杂时序数据特征的学习能力,促进智能决策支持应用。 阅读建议:此资源不仅提供了详细的代码实现和模型架构解析,还深入探讨了模型优化和实际应用中的挑战与解决方案。因此,在学习过程中,建议结合理论与实践,逐步理解各个模块的功能和实现细节,并尝试在自己的项目中应用这些技术和方法。同时,注意数据预处理的重要性,合理设置模型参数与网络结构,控制多步预测误差传播,防范过拟合,规划计算资源与训练时间,关注模型的可解释性和透明度,以及持续更新与迭代模型,以适应数据分布的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值