您的位置:首页 > 其它

Huffman Tree、AVL、SplayTree、Skip List、2-3-4 Tree、rb-Tree、B-Tree特性辨析与总结

2016-08-07 18:56 411 查看

赫夫曼树(Huffman Tree):

赫夫曼树,又称最优树,是一类带权路径最短的树,应用广泛。说到路径,就存在路径长度和带权路径长度的概念,路径长度表示树中一个节点到另一个节点之间的路径上的分支和,考虑带权的节点,节点的带权路径长度为从该节点到树根的路径长度与节点上权的乘积,树的带权路径长度为树中所有叶子节点的带权路径之和。带权路径长度最小的二叉树称为赫夫曼树
如何构造赫夫曼树呢?赫夫曼最早给出了一个带有一般规律的算法,俗称赫夫曼算法。现叙述如下:

根据给定的n个权值{w1,w2,w3...wn}构成n棵二叉树的集合F={T1,T2,T3...Tn},其中,每棵二叉树Ti中只有一个带权为Wi的根节点,其左右子树为空。
在F中选择两棵根节点的权值最小的树作为左右子树构成一棵新的二叉树,且新二叉树的根节点的权值为其左右子树的节点的权值之和。
在F中删除这两棵树,同时将新二叉树加入F中。
重复2和3直到F只剩下一棵树为止,这棵树就是赫夫曼树。

赫夫曼树主要用于数据编码。在通信过程中,为了节省资源,采用边长码,经常使用的字符编码短,不常使用的字符编码长;而且为了满足立即可解码性,必须人一个字符的编码不能是另一个字符的编码的前缀,即前缀编码。
设计电文总长最短的二进制前缀编码,即以n中字符出现的频率作为权值,设计一棵赫夫曼树的问题,由此得到的二进制前缀编码便称为赫夫曼编码

平衡二叉树(AVL):

AVL树是对二叉查找树(BST)的一种改进。BST用来协助在树中查找指定项,项被插入BST的次序决定了树的形状以及查找操作的效率。与偏向一侧的不平衡树相比,每层基本上都是满的树之上的查找操作更为有效。
AVL树的递归概念:树要么是空树,要么左右子树都是AVL树,且左右子树的高度差不超过1。
AVL树的操作与BST类型,不同之处在于进行元素的插入和移除之后要经过旋转,以保证树的平衡,具体参见《
4000
二叉树及其延伸:BST、AVL、SplayTree、SkipList》一文。

伸展树(Splay Tree):

在实际情况中,90%的访问发生在10%的数据上。因此,我们可以重构树的结构,使得被经常访问的节点朝树根的方向移动。尽管这会引入额外的操作,但是经常被访问的节点被移动到了靠近根的位置,因此,对于这部分节点,我们可以很快的访问。这样,就能使得平摊复杂度为logN。伸展树就是基于这一原理。
对一个二叉搜索树执行一系列的查找操作。为了使整个查找时间更小,被查频率高的那些条目就应当经常处于靠近树根的位置。于是想到设计一个简单方法,在每次查找之后对树进行重构,把被查找的条目搬移到离树根近一些的地方。splay tree应运而生。splay tree是一种自调整形式的二叉搜索树,它会沿着从某个节点到树根之间的路径,通过一系列的旋转把这个节点搬移到树根去。
伸展树(Splay Tree)是一种二叉搜索树,它能在O(log n)内完成插入、查找和删除操作。它的优势在于不需要记录用于平衡树的冗余信息。在伸展树上的一般操作都基于伸展操作。 

跳表(Skip List):

Skip List是一种随机化的数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(log n)平均时间)。基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表(因此得名)。所有操作都以对数随机化的时间进行。Skip List可以很好解决有序链表查找特定值的困难。
它的效率和红黑树以及 AVL 树不相上下,但跳表的原理相当简单,只要你能熟练操作链表,就能轻松实现一个 SkipList。
一个跳表,应该具有以下特征:
一个跳表应该有几个层(level)组成;
跳表的第一层包含所有的元素;
每一层都是一个有序的链表;
如果元素x出现在第i层,则所有比i小的层都包含x;
第i层的元素通过一个down指针指向下一层拥有相同值的元素;
在每一层中,-1和1两个元素都出现(分别表示INT_MIN和INT_MAX);
Top指针指向最高层的第一个元素。

2-3-4 Tree:

2-3-4 Tree是一种自平衡的树结构,其为红黑树一种等同结构。
2-3-4 Tree的定义和规则:每个节点可以有2个,3个,最多4个子节点,而key的个数则为1个,2个,最多3个。
那么2-3-4树如何实现的自平衡呢?以插入为例,插入的规则如下:
1. key只插入到叶节点中;
2. 当叶节点的key已满而无法插入的时候,需要对节点进行拆分。将中间节点移到父节点中,从而使当前节点可以容纳新的key。
这时有可能出现这种情况,当将中间节点移到父节点时,父节点的key已满,则父节点也需要进行拆分。这样导致情况变得复杂。所以在2-3-4的实现中,会在插入的过程中,对经过的节点进行检查,将这种情况“扼杀”于摇篮之中。即从根节点开始,由上而下,遇到一个已满的节点就对其进行拆分。这样,当到达叶节点的时候,该节点可以直接插入新的key。

红黑树(rb-Tree):

所谓红黑树,就是平衡的扩充二叉搜索树,红黑树与AVL都是BST的平衡版本,相比AVL的完全平衡,红黑树只要求局部平衡,它保证没有一条路径会比其他路径长出俩倍,因而是接近平衡的,当向红黑树中插入和删除节点时,需要的调整比AVL要少,统计性能要好于AVL树,C++ STL中的map、set、multimap和multiset都应用了红黑树的变体。
红黑树的特点:
红黑树的根节点为黑色
红黑树中扩充的外部节点都是黑色节点
红色节点的两个子节点都是黑色节点,不允许两个连续的红色节点
任何节点到其子孙的外部节点的每条简单路径都包含相同数目的黑色节点

B-Tree:

B树,一种平衡的多叉树,其定义如下:
一棵m阶的B树满足下列条件:
树中每个结点至多有m个孩子;
除根结点和叶子结点外,其它每个结点至少有m/2个孩子;
若根结点不是叶子结点,则至少有2个孩子;
所有叶子结点(失败节点)都出现在同一层,叶子结点不包含任何关键字信息;
所有非终端结点中包含下列信息数据 ( n, A0 , K1 , A1 , K2 , A2 , … , Kn , An ),其中: Ki (i=1,…,n)为关键字,且Ki < Ki+1 , Ai (i=0,…,n)为指向子树根结点的指针, n为关键字的个数
非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
在B树中,每个结点中关键字从小到大排列,并且当该结点的孩子是非叶子结点时,该k-1个关键字正好是k个孩子包含的关键字的值域的分划。因为叶子结点不包含关键字,所以可以把叶子结点看成在树里实际上并不存在外部结点,指向这些外部结点的指针为空,叶子结点的数目正好等于树中所包含的关键字总个数加1。B树中的一个包含n个关键字,n+1个指针的结点的一般形式为:   (n,P0,K1,P1,K2,P2,…,Kn,Pn)其中,Ki为关键字,K1 <K2 <… <Kn,   Pi   是指向包括Ki到Ki+1之间的关键字的子树的指针。
特性
关键字集合分布在整颗树中;
任何一个关键字出现且只出现在一个结点中;
搜索有可能在非叶子结点结束;
其搜索性能等价于在关键字全集内做一次二分查找;
自动层次控制
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息