2019-9-23 堆

一、概念:
1、(1)逻辑上 完全二叉树
(2)物理上 数组
(3)满足任意结点的值都大于其子树中结点的值叫做大堆,或者大根堆,或者最大堆
(4)反之,则是小堆,或者小根堆,或者最小堆
如图为大堆和小堆在这里插入图片描述
2、下标关系:(已知双亲(Parent)的下标)
左孩子下标:array[ left ] = 2parent+1;
右孩子下标:array[ right ] = 2
parent + 2 ;
已知孩子(不分左右孩子)(child)下标,则:
双亲下标:array[ parent ]= (child -1 ) / 2 ;
3、堆的基本作用是,快速找集合中的最值

二、操作
1、向下调整
前提:左右子树都是一个堆才能调整
说明一点:堆问题中的 size 代表数组中被视为堆数据的个数;
调整的过程(以小堆为例)
在这里插入图片描述
自己总结:1)判断左孩子;
2)找左孩子的下标,并比较是否越界;
3)根据array[left] 与 array[right] 比较出min
4)判断min与array[index]的值,若min小,令array[index]=min,反之调整结束
5)重复以上操作

在这里插入图片描述
如图,调整前,int[] array = { 27,15,19,18,28,34,65,49,25,37 };
调整后,int[] array = { 15,18,19,25,28,34,65,49,27,37 };
操作向下调整的时间复杂度 O(log(n)) 空间复杂度O(1)2、
2、建堆
一个数组逻辑上可以看做一颗完全二叉树,但它还不是一个堆,将其构建成一个堆:
从倒数第一个非叶子结点的子树开始调整,一直调整至根节点,即可调整成堆
在这里插入图片描述
建堆操作:
时间复杂度为 O(n) | O(n*log(n)),空间复杂度为O(1)

三、堆的应用:优先级队列
1、内部原理:用堆来构建
2、主要操作:
(1)入队列
以大堆为例:
1)将元素尾插至数组;
2)比较其与双亲结点的大小,若该元素的值大,插入结束
3)反之,交换其与双亲结点中大的元素,重新进行2、3步骤
4)直到根结点在这里插入图片描述
(2)出队列:(优先级最高)
为了防止破坏堆的结构,删除时并不是直接将堆顶元素删除,而是用数组的最后一个元素替换堆顶元素,然后通过向下调整方式,进行重新调整成堆
在这里插入图片描述(3)返回队首元素:(优先级最高)
直接返回堆顶元素即可
3、Java中的优先级队列:
在这里插入图片描述

发布了78 篇原创文章 · 获赞 4 · 访问量 4173

猜你喜欢

转载自blog.csdn.net/weixin_43580746/article/details/101223173