1. Binary tree: Heap
定义:一个node下最多有两个子节点,且父节点的值要大于子节点的值。因此,针对这种tree,最大值永远在根节点上,越往下,值越小。下图左侧则为正确的heap,而右侧由于上方节点的值比下方节点的值小,因此其不是一个heap。
Basic operation 1: GetMax
要获得最大值的元素,只需要返回根元素的值即可。
因此只需要一次操作,Running Time = O(1)
Basic operation 2: Insert
假设我们要插入的值为32:
1. 图二:将32随意附着到最底部的某个节点(附着后的子节点不能超过3个)
2. 图三:附着后可以发现,子节点的值大于其父节点,将7和32的位置进行交换
3. 图四:交换位置后最新的顺序
4. 图五:交换后此时子节点的值还是大于父节点,将29和32的位置进行交换
5. 图六:交换位置后最新的顺序,此时所有父节点的值都大于了子节点
Running time = O(tree height)
Basic operation 3: ExtractMax
1. 图二:首先把根节点的值和任意一个最末的子节点进行交换,同时去掉根节点的值
2. 图三:交换后,我们得到一个新的tree,此时根节点的值比子节点的值小
12小于29,也小于18
如果我们将12与18进行交换的话,18还是要与29进行交换
因此当父节点的值比两个子节点的值都小的时候,我们将其与较大的值进行交换
即将12与29进行交换
3. 图四:交换值后,得到一个新的tree
4. 图五:此时的父节点的值大于子节点,因此我们还要进行交换
5. 图六:交换后,得到一个新的tree,此时所有父节点的值都大于了子节点
Running time = O(tree height)
Basic operation 4: ChangePriority
假设我们把12的值变成了35:
由于此时35大于其父节点,因此我们要sift up
1. 首先把35和18交换位置
2. 此时35还是比其父节点大,因此我们还需要继续交换位置,直到其夫节点的值大于它的值
同理,如果我们把第二层左边节点的29变成12,此时12小于子节点的值,因此我们要sift down
Sift down的逻辑和extractMax一致
Running time = O(tree height)
Basic operation 5: Remove
如果我们要删除18:
1. 首先我们将18变成正无穷
2. 执行ChangePriority的操作,完成后正无穷的位置将到达根部
3. 执行ExtractMax的操作,此时正无穷将被去掉同时树的顺序将会被重新整理
Running time = O(tree height)
总结
除了getMax的运行时间为1之外,其余操作的运行时间都为tree height
那么由此可见,要想运行时间变短,我们就要将树的高度变矮
那如何将树的高度变矮呢?--> Complete binary tree
Complete Binary Trees
定义:所有节点均有两个子节点。只有最末层允许有单个节点的出现,但是必须遵守从左往后被填充的逻辑。
Advantage 1: 树的层数变低
一个n个节点的complete binary tree,其高度最多 = O(log n)
Advantage 2: Store as Array