二叉树,二叉排序树,红黑树 学习
Posted 为民除害
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树,二叉排序树,红黑树 学习相关的知识,希望对你有一定的参考价值。
二叉排序树是一种比较有用的折衷方案。
数组的搜索比较方便,可以直接用下标,但删除或者插入某些元素就比较麻烦。
链表与之相反,删除和插入元素很快,但查找很慢。
二叉排序树就既有链表的好处,也有数组的好处。
在处理大批量的动态的数据是比较有用。
二叉树数据结构:
typedef struct _BiTNode { int data; _BiTNode *leftChild; _BiTNode *rightChild; }BiTNode, *pBiTree;
二叉树的创建和遍历:http://blog.csdn.net/pony_maggie/article/details/38390513
=======================================================================
二叉排序树
http://www.cnblogs.com/zhuyf87/archive/2012/11/09/2763113.html
数据结构同上,规定如下:
1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
3. 它的左、右子树也分别为二叉排序树。
中序遍历(左中右)二叉排序树可得到一个依据关键字的有序序列
搜索、插入、删除的时间复杂度等于树高,期望O(logn),最坏O(n)(数列有序,树退化成线性表,如右斜树)。
虽然二叉排序树的最坏效率是O(n),但它支持动态查找,且有很多改进版的二叉排序树可以使树高为O(logn),如平衡二叉树AVL、红黑树等。
=======================================================================
平衡二叉树AVL(建立在二叉排序树之上!)
http://www.cnblogs.com/fornever/archive/2011/11/15/2249492.html
平衡二叉树定义(AVL):
它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。
平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;
要理解,如图两个节点之间的变换,可以继续保持平衡二叉树的规则!
节点1和节点2,1可以作为2的左孩子,2可以作为1的右孩子。
同理,3可以作为2的右孩子,2可以作为3的左孩子。
插入:
最小不平衡子树的根结点:也就是当你进行插入操作时,找到该需要插入结点的位置并插入后,从该结点起向上寻找(回溯),第一个不平衡的结点即平衡因子bf变为-2或2。
为什么要引入这个最小不平衡根结点的概念,因为在插入时,对该子树进行保持平衡操作后,其它的结点的平衡因子不会变,也就是整棵树又恢复平衡了。
为什么呢?
看图理解不平衡子树的旋转方式:
y是插入的节点,x是最小不平衡子树的根。
插入部位在左左
第一种情况,瞬间秒懂,因为我上边说了那个变换规则。
第二种情况,a和x变换,d变成x的左孩子。(因为肯定是二叉排序树,x左子树的所有节点都比x小!)
变换的意思是,节点A要覆盖储存节点X的那块内存上,
变换过程:
变换的节点,要连带着各自的子树。如图2,
变换时,节点X带着自己的子节点B,节点A则带着自己的子节点-c-y和-d。即
变换后,发现节点a有三个子树了,擦,给多出来的d找个合适的位置(按大小找到位置),安置一下。
右右
左右
要经过两次变换的。
右左
那么如何找到最小不平衡子树的根结点x,并判断出它是属于那种情况的?
看原博文吧,这里不管代码实现。
可以在判定了之后,调用keepBalance函数,使二叉树保持平衡。
原文中有 删除 和 插入。
=======================================================================
红黑树
2. 其次,AVL的结构相较RB-Tree来说更为平衡,
作者:Acjx
链接:http://www.zhihu.com/question/20545708/answer/58717264
。
以上是关于二叉树,二叉排序树,红黑树 学习的主要内容,如果未能解决你的问题,请参考以下文章