https://blog.csdn.net/u010452388/article/details/81283998
堆:每个节点都大于它子树的节点;是个完全二叉树。(用一维数组存储)
第i个元素的:
父亲:(i-1)/2
孩子: i*2+1 i*2+2
第1层标为0 ... 第h层最多有2的h次方个元素。h层最少一共有2的h+1幂个元素。
1,堆化数组,用自顶向下。在O(n)可完成。即只要排好第一个最大元素即可。构造出最大值堆。
1.1 构造堆,用自底向上。从第一个开始。需用nO(n).
2,自顶向下:从尾部开始做倒着往前,对每一个元素做自顶向下。叶子节点肯定都满足堆条件。第一个非叶子节点是 (n-1)/2做自顶向下(下面都是叶子,满足排好序了)。即从这里向下面的子树堆化。当前节点,找到它的两个子节点,从两个子节点中找出较大的。看当前节点是否大于较大的;是则较大成为当前节点;否则和当前和较大交换。继续做直到递归到底部。 O(log n)
自底向上:对一个初始乱序完全二叉树,从顶部开始,对每一个节点做自底向上。找它的父元素,确保都满足堆。第一个元素认为一个堆树,父为null,满足堆。第二个和它的父亲比较,不满足则交换;第三个类推。后面的都是,注意要一直和父类递归,直到顶端。
3,堆的删除。堆想象成苹果堆,只能取上面第一个。删除也只能删除第一个最大元素。删除后只能最后一个补上来(否则中间元素补上来,最后会空缺,不是完全树了),让这个补上来的位于第一个位置的做自顶向下堆化。 O(log n)
4,堆的插入: 扩大空间,插入到数组末尾(还是完全树)。执行自底向上堆化。 O(log n)
5, 最大元素:直接取 O(1)
6,排序:将最大值堆。第一个与最后一个交换。做个自顶向下。第一个与倒数第二个交换,做自顶向下。以此类推。