数据结构 - 堆

堆的主要性质

1、堆有两种:大顶堆和小顶堆,大顶堆是指每个结点的值都大于其左右孩子的值(小顶堆反之)。

2、堆和数组下标的关系

根结点是从 0 开始存储,所以假设某个元素为序号为 i ,那么其左子树的位置是 2i+1 ,其右子树的位置是 2i+2 ,其父节点的位置是 (n-1)/2 。

3、堆和树的关系

堆是完全二叉树,完全二叉树:(1)除最后一层外,每一层上的节点数均达到最大值;(2)最后一层只缺少若干右边结点。

4、堆和栈的关系

栈内存由操作系统来分配和释放,堆内存由程序员自己分配和释放。

5、堆排序的时间复杂度为O(NlogN)


堆排序

一、构造初始堆

1、初始化堆是对所有非叶子结点进行筛选,筛选只需要从第[n/2](向下取整)个父结点开始,从后往前进行结点的调整。

2、父结点调整

(1)父结点调整的目的是让父结点以后的分支都满足大顶堆或小顶堆的性质。

(2)具体步骤

如果父、左儿子和右儿子中,父是最大值,则不需要调整;

如果父不是最大值,则先把父与最大儿的值交换,再递归判断最大儿处结点是否需要调整。

二、堆排序

1、将array[0]与最后一个元素交换,这样最后一个结点就是最大值,然后在 0~n-2 范围内进行根结点调整;

2、将array[0]与倒数第二个元素交换,再在 0~n-3 范围内根结点调整;

3、重复以上步骤 array.length-1 次。


DEMO

public class MyHeapSort {

	static int[] array;
	
	public static void main(String[] args) {
		input();
		heapSort(array);
		output();
	}

	static void input(){
		System.out.println("请输入一个数组,数字之间以英文逗号分隔:");
		Scanner scanner = new Scanner(System.in);
		String string = scanner.next().toString(); //读取输入,直到遇到空格或换行,并转化为字符串。
		String arrayString[] = string.split(","); // 分割为字符串数组
		array = new int[arrayString.length]; // 定义数组长度
		for(int i=0;i<array.length;i++){
			array[i] = Integer.parseInt(arrayString[i]); // 整型化
		}
	}
	
	static void output() {
		 System.out.println("经过堆排序后,结果如下:");
		 for(int i=0;i<array.length;i++)
			 System.out.print(array[i] + " ");
	 }
	
	static void heapSort(int[] array){
		int temp;
		// 构建初始化堆
		buildMaxHeap(array); 
		// 堆排序
		for(int i=array.length-1;i>0;i--){ // n个数需要n-1次的结点交换和调整 
			temp=array[0]; array[0]=array[i];array[i]=temp; // 交换array[0]与array[i]
			fatherNodeAdjust(array, i, 0); // 在 0~i 内进行结点调整
		}
	}
	
	static void buildMaxHeap(int[] array) { // 构建初始化堆
		// 由于完全二叉树的性质,只需要从第[n/2]个父结点开始,从后往前进行父结点调整。
        int half = array.length / 2; 
        for (int i = half; i >= 0; i--) {  
        	fatherNodeAdjust(array, array.length, i); 
        }  
    }  
	
	static void fatherNodeAdjust(int[] array, int heapSize, int index) { // 父结点调整
        int left = index * 2 + 1; // 左孩子
        int right = index * 2 + 2; // 右孩子 
        int largest = index; // 暂时将父结点定为最大值
        int temp;
        // 先要判断左儿子是否存在,再判断左儿子是不是更大。
        if (left<heapSize && array[left]>array[index]) { 
            largest = left;  
        }  
        // 右儿子是否存在,右儿子是否更大。
        if (right<heapSize && array[right]>array[largest]) { // 右孩子存在且右孩子更大
            largest = right;  
        }  

        if (index != largest) { 
        	// 如果发现父不是最大值,则父与最大儿交换,以确保父最大。
        	temp = array[index]; array[index]=array[largest]; array[largest]=temp; 
        	// 父放在最大儿位置上,是否满足最大堆的性质,还需调用递归maxHeap()来调整。
        	fatherNodeAdjust(array, heapSize, largest); 
        }  
    }  
}



常见题目

下列数据结构不是多型数据类型的是()

A  堆    B  栈    C  字符串    D  有向图


下标从1 开始,在含有n个关键字的小根堆中,关键字最大的记录有可能存储在()位置上

A  [n/2]    B  [n/2]-1    C  1    D  [n/2]+2

【解析】

小根堆中最大的数一定是放在叶子节点上

堆本身是个完全二叉树

完全二叉树的叶子节点的位置大于 n/2 

选D






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值