是什么
二叉树。//是完全二叉树(除了叶子节点,其他层的节点都是满的)。不是满二叉树(叶子节点都是满的)。
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数据结构和算法