二叉查找树(BST) 自平衡二叉搜索树(RBT、AVL)

二叉查找树(BST) 自平衡二叉搜索树(RBT、AVL)

二叉查找树
http://www.cnblogs.com/gaochundong/p/binary_search_tree.html
二叉查找树
http://blog.jobbole.com/79305/
动态查找树比较
http://www.iteye.com/topic/614070

无序链表和有序数组,无序链表在插入的时候具有较高的灵活性,而有序数组在查找时具有较高的效率,
二叉查找树(Binary Search Tree,BST)这一数据结构综合了以上两种数据结构的优点。可以快速的查找二叉树(相对于链表),还可以迅速的在二叉树中插入和拆除数据(相对于数组)
二叉查找树具有很高的灵活性,对其优化可以生成平衡二叉树,红黑树等高效的查找和插入数据结构

二叉查找树(Binary Search Tree)
也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
1. 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 任意节点的左、右子树也分别为二叉查找树。
4. 没有键值相等的节点(no duplicate nodes)
二叉查找树是一种动态查找表,可以进行动态地插入和删除

二叉树遍历是本质上是将非线性结构线性化。

二叉树深度优先遍历
D 二叉树的某一结点,L ,R 分别为结点D的左右树。
先序 DLR DRL
中序 LDR RDL
后序 LRD LRD

深度优先遍历:
搜索子孙节点再搜索节点的兄弟节点。
广度优先遍历:
先搜索所有兄弟节点,再搜索子孙节点。
二叉查找树容易实现:
查找特定值,找到最下值 ,找最大值。

自平衡二叉搜索树
自平衡二叉搜索树可以自动调节节点的位置,以保证树的深度始终是最小值(树的深度是指根节点到最深叶节点的距离)。
保证深度足够小可以让树的各种操作效率变高。但二叉搜索树保持自平衡会产生较大的时间开销。 实现自平衡树的两种著名数据结构是红黑树和AVL树。

红黑树(RBT)
AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
红黑树是弱平衡的(只要求部分地达到平衡要求),用非严格的平衡来换取增删节点时候旋转次数的降低(即降低了对旋转的要求),从而提高了性能;

红黑树上每个节点内含五个域:
color,key,left,right,p。如果相应的指针域没有,则设为NIL。
红黑树需满足特性:
1、每个结点要么是红的,要么是黑的。
2、根结点是黑的。
3、每个叶结点,即空结点(NULL)是黑的。
4、如果一个结点是红的,那么它的俩个儿子都是黑的。
5、对每个结点,从该结点到其子孙结点的所有路径上包含相同数目的黑结点。

红黑树特点:
1、由于它的设计,任何不平衡都会在3次旋转之内解决。
2、红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。
3、红黑树并不适应所有应用树的领域。如果数据基本上是静态的,让其保持在能够插入且不影响平衡的地方会具有更好的性能。
如数据完全是静态的,做一个哈希表,性能可能会更好一些。
4、红黑树是一个更高效的检索二叉树,红黑树进行搜索、插入、删除的时间复杂度均为O(log2(n)),常常用来实现关联数组。典型地,JDK提供的集合类TreeMap本身就是一个红黑树的实现。

AVL树
AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。
查找、插入和删除在平均和最坏情况下都是O(logn)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

AVL树的定义:
一棵AVL树满足以下的条件:
1、它的左子树和右子树都是AVL树
2、左子树和右子树的高度差不能超过1
性质:
1、一棵n个结点的AVL树的其高度保持在0(log2(n)),不会超过3/2log2(n+1)
2、一棵n个结点的AVL树的平均搜索长度保持在0(log2(n)).
3、一棵n个结点的AVL树删除一个结点做平衡化旋转所需要的时间为0(log2(n)).

为了保证平衡,AVL树中的每个结点都有一个平衡因子(balance factor,BF),它表示这个结点的左、右子树的高度差,也就是左子树的高度减去右子树的高度的结果值。
AVL树上所有结点的BF值只能是-1、0、1。反之,只要二叉树上一个结点的BF的绝对值大于1,则该二叉树就不是平衡二叉树。

AVL树的旋转规律
LL型、RR型、LR型、RL型
AVL树的基本操作
1、插入
向AVL树插入可以通过如同它是未平衡的二叉查找树一样把给定的值插入树中,接着自底向上向根节点折回,于在插入期间成为不平衡的所有节点上进行旋转来完成。
因为折回到根节点的路途上最多有1.5乘log n个节点,而每次AVL 旋转都耗费恒定的时间,插入处理在整体上耗费 O(log n) 时间。 
2、删除
从AVL树中删除可以通过把要删除的节点向下旋转成一个叶子节点,接着直接剪除这个叶子节点来完成。
因为在旋转成叶子节点期间最多有log n个节点被旋转,而每次AVL旋转耗费恒定的时间,删除处理在整体上耗费O(log n)时间。
3、查找
在AVL树中查找同在一般BST完全一样的进行,所以耗费 O(log n) 时间,因为AVL树总是保持平衡的。不需要特殊的准备,树的结构不会由于查询而改变

你可能感兴趣的:(数据结构)