什么是堆?
堆结构+偏序关系
任何关于堆的算法都要先保证其一,再尽力做好另一个
FixHeap()
先保证堆结构不被破坏,即将最后一个放在第一个的位置,然后再利用左右子树只需修一个树的局部完整性达到log(n)的效果
CreateHeap()
对左右子树递归的执行算法,然后fix头部即可, w ( n ) = 2 w ( n / 2 ) + l o g n w(n)=2w(n/2)+logn w(n)=2w(n/2)+logn
堆排序的优化
针对FixHeap进行优化:
在FixHeap()的时候,需要确认三者的大小关系,这使我们的复杂度达到了 O ( 2 n l o g n ) \Omicron(2nlogn) O(2nlogn),为使得系数降低,关键就在于我们以什么手法找到顶部元素该有的位置:
FixHeap(int root,int h)
1. 若正在向下FIX,则将root与其两子最小的一个交换,更新root,并迭代的做h/2次(若无子则进入第三步)
2. 若正在向上Fix且比其父大(比其父小则算法终止,FIX完成),则将root与其父交换,更新root,并迭代的做h/2次(若到了此步,算法一定会在此步的过程中终止)
3. if root比其父小,向上FixHeap(root,h)
4. else if root不是它与两子中最小的(无子则终止),则更新h=h/2+1,向下FixHeap(root,h)
5. else 算法终止,FIX完成
堆的泛化
多叉树:使得下沉变得困难,而上浮变得容易,此时就需要调整h/k 的k的大小使之高效
堆的性质
- 堆的第k大数在前K层
- ∑ h ≤ h − 1 \sum_{h}\le h-1 ∑h≤h−1
- 若从1开始计数
- 左孩子: 2 i 2i 2i,右孩子 2 I + 1 2I+1 2I+1
- 父: i / 2 i/2 i/2