堆、二叉树
二叉树可以用数组形式保存吗?
可以,按层序的方式把值平铺在数组中
非完全二叉树平铺到数组中时,会有很多空洞,所以往往不用这种方式
关注下标表的变化:
已知parent下标: 左孩子下标left=2*parent+1
右孩子下标right=2*parent+2
已知chid下标(不分左右):parent=(chid-1)/2
堆:1、在逻辑上是一棵完全二叉树
2、物理上是一个数组
3、任意位置的值>=它的左右孩子的值(大堆)
反之(小堆)
堆的基本功能:找最值的
关于堆,有以下几个重要操作:
向下调整(堆化):
前提:在整个堆中,除了要调整的位置之外,其余位置都已经满足堆的性质了
(如果要调整的位置是叶子,调整结束)
1、找到两个孩子中最大的一个孩子,
2、比较最大孩子的值和要调整位置的值
1、如果满足堆的性质了,调整结束
2、否则,交换两个的值
3、继续调整原来最大孩子的位置
(判断是否是叶子,左右孩子的下标越界>=size)
三种情况:
只有左孩子: =》左孩子
左右都有,左孩子大 : =》左孩子
左右都有,右孩子大: =》右孩子
建堆:任意数组转成堆
从最后一个非叶子结点:最后一个结点的双亲
最后一个结点的下标:size-1
如果算法中出现了二叉树(接近完全二叉树)
如果算法的消耗时间和高度有关
1、结点个数是n:时间复杂度是O(log(n))
2、最后一层结点个数是n:时间复杂度是O(log(n))
log(1000) 约为10
log(100万) 约为20
log(10依) 约为30
建堆的应用:1、队列(优先级队列)
1)在java语言中,PriorityQueue
2)实现优先级队列如何实现,在经常性的插入和删除中保持优先级是最好的
TopK问题: 在海量数据中(亿亿级别),找最大的K(K小)个数