堆,AVL树,红黑树以及优先级队列

晨曦之光 发布于 2012/04/10 15:03
阅读 618
收藏 0

【Gopher China万字分享】华为云的Go语言云原生实战经验!>>>

声明:本文完全没有定量分析,需要定量分析的,请随便查阅一本数据结构的书籍或网页。
二叉堆:拥有删除最大(小)权值节点以及插入任意节点操作,是一颗完全二叉树,其完全性由插入和删除动作来保证。
先看看什么是完全二叉树,不过为了引出完全二叉树的定义还要先看看什么是满二叉树:所有叶子节点都在同一层的二叉树,并且树高h和节点数满足:节点数目为 2*h-1。完全二叉树就是:深度为h节点数目为n的完全二叉树的每个节点都与深度为h的满二叉树的节点从1到n一一对应。
进一步看看插入和删除最值节点如何满足二叉堆的完全性。先看插入,插入的初始位置应该是叶子节点,哪个叶子节点呢?是最后一层从左到右的下一个叶子节点,如下图:
        x                                x                                   x
       / /                              /  /                                / /
      x   x              或者      x    x         或者                x   x
     / /                              / /   /                             /
    x   here                    x   x  here                        here
然 后怎么办呢?然后就是比较了,和其父亲比较,以最大堆为例,如果它比它父亲大,那么就交换父子节点,然后继续和新父亲比较(按说该是祖父了,这里用父节点子节点并不合适),直到比较大小因小于父节点而停下或者到达根,这样在比较过程中没有涉及兄弟也没有进行结构调整,只是位置对调而已,因此初始插入时的结 构并没有被破坏,而初始插入的规则(如上图)保证了堆的完全性,故插入操作保证了二叉堆的完全性。
再看看删除,删除对于堆的意义和其他二叉树并不相同,它仅仅删除根元素,那么保证二叉树完全但不保证其他的最快方式就是用最底层最右边的节点来填入根,但是怎么保证堆的性质呢?还是比较,这回就是和孩子比较了,孩子有两个,对于最大堆就是要和最大的孩子比较,对于最小堆则相反。下面引用一个小算法来说明删 除和插入,代码很简单的。
void Delete(int heap[],int n)
{
      int x = heap[n];
      int i = 1,ci = 2;
      while (ci<=n)
      {
          if (ci         ci++;
          if (x >= heap[ci])
        break;
          heap[i] = heap[ci];
          i = ci;
          ci *= 2;
      }
      heap[i] = x;
}
void Insert(int heap[],int n,int x)
{
      int i = ++n;
      while ( i! = 1 && x > heap[i/2] )
      {
          heap[i] = heap[i/2];
          i /= 2;
      }
      heap[i] = heap[i/2];
}
二 叉堆是实现优先级队列的一种绝佳的数据结构。如果每次都取优先级最高的话(也就是取树根),但是要想到删除或查找特定的结点的情况,这样堆本身就不好调整了,因为对于删除,默认的二叉堆中并没有删除任意节点的操作,因此可扩展性会受到很大影响,对于查找,二叉堆并不是一颗查找树,只是保证最值在根,对于孩 子节点的大小顺序没有任何规定。于是想一下红黑树还有avl树,这棵树是自调整的,总会将权值最小的置于树的最左边最下边,这样我们取最左下的节点就可以 得到一个极值,完成了二叉堆的功能,考虑删除,红黑树定义了删除,插入,查找等一系列动作,扩展性好于二叉堆。所以可以说二叉堆仅仅适用于完全的优先级队列管理,一旦涉及别的操作就麻烦了,而红黑树等平衡树在可以胜任二叉堆的任务的情况下还可以采取更多的动作。avl树和红黑树都是平衡二叉搜索树(某种意义上红黑树并不平衡),它们的意义有两个:1.搜索树,这决定了它们的功能;2.平衡树,这决定了它们的效率。对于红黑树还有一点,就是不那么平衡,减少了限制条件总会使事情变得简单,在这个世界,只要有限制,那么就要有一定的开销来维护这个限制,毕竟,世间万物都是趋向自由的,无约束的(呵呵,题外 话)。所以姑且不从统计学上分析,仅仅从上面的哲学意义上,红黑树就比avl树要高效,实际上确实高效,但是有个前提,就是必须是综合应用(查找,插入, 删除)而不是仅仅查找,要是只有查找操作的话,avl要好,因为它严格用平衡因子来限制平衡,相同节点的avl树的最大高度要低于红黑树的最大高度,而查找的效率直接和最大高度相关联。好了,以后我会具体说一下这两棵树。


原文链接:http://blog.csdn.net/dog250/article/details/5303298
加载中
返回顶部
顶部