156 阅读3分钟

是什么

二叉树。//是完全二叉树(除了叶子节点,其他层的节点都是满的)。不是满二叉树(叶子节点都是满的)。


1.以前是二叉搜索树,即二叉有序树
2.堆只是父子节点有序,即子节点比父节点小——最大的父节点是最上边的那个根节点。其他的节点都是无序的。

如何实现堆这种数据结构/树?

基于数组这种数据结构 //最佳实践

应用场景

1.删除最大数据 //即删除根节点
2.插入新的节点

删除最大节点

步骤
1.删除数组的第一个元素
2.把数组最后一个节点复制到根节点的位置(即数组的第一个元素) //如果不满足堆的条件,那么向下比较两个子节点 //如果

插入新的节点

步骤
插入到数组的最后一个元素 //如果不满足堆的条件,向上比较一个父节点。因为只和一个父节点比较,所以相对来说,插入比删除更简单一点。

堆排序

堆这种数据结构可以用来排序。

步骤
1.先按堆的条件插入 //父子节点有序
2.再删除根节点 //每次删除的都是最大数据,所以top N就是删除n个数据即可得到top N

流程
无序数组——》堆树——》remove到有序数组

速度

N * logN //和快速排序一样,但是比快速排序慢一点点,因为需要比较父子节点

空间

一个数组n //很节约空间

注:同一个数组可以存放输入数据-数组、堆二叉树、输出数据-数组。

优先级队列

队列
先进先出。


根节点优先级最高。
父节点比子节点优先级高。

所以,优先级的作用是,上面的优先级高,先从上面获取;下面的优先级低,后从下面获取。


怎么实现?
使用堆二叉树实现。//最佳实践


应用场景
1.堆排序 //堆就是优先级队列,是优先级队列的一种,而且优先级队列最佳实践是使用堆二叉树来实现。

2.操作系统任务调度有优先级

3.多线程也有优先级

Top K问题

思想
基于最大堆或最小堆。目的是把速度从logN降到logK。

堆的大小是K,即top K中的K。


步骤
1.堆数据未满
插入堆

2.堆数据已满
和堆的根数据比较
1)大于
2)等于
3)小于

除了比较数据,还需要维持堆的弱序特性。因为堆的数据数量是K,所以速度是logK。

3.比较完成
最终堆里的数据就是top K。


总结
书里给出了两种解决方案,一个简单点,一个是堆
1.快速排序
2.堆


参考
剑指offer

参考

java数据结构和算法