现在发现二叉树和树讲起来真的是没完没了,刚发表博客之后发现,那还不足以表述这颗大树。我们继续完善。
树与二叉树遍历确实很重要,但是还有一些你也许忘记的重要知识点,我们再来看一下还有什么好玩的:我不太喜欢太深奥的东西,所以我一般以我能理解的简单的方法去说说这些知识点。
树与二叉树的转换
我们都知道二叉树与树不同,因为二叉树是有讲究的,比如:二叉树第i层最多只有2的i次方个结点,所以当把树转换成二叉树的时候。我们是有窍门的,还是用图来说话,我们接下来也来看这么一张图,看看到底是怎么个转换的:
这一看就知道是树,因为不符合我们二叉树的特点,比如结点3带的叶子结点就不符合我们二叉树的要求了,所以我们要想办法去转换成二叉树。
很简单,就一句话:树的左孩子结点作为二叉树的左子树结点,兄弟结点作为二叉树的右子节点。我们看图是怎么转换的:
在这个图里边,2是根结点的左子树结点,与2并列的3、4是2的兄弟结点,故转换成二叉树时,作为2的右子节点,类似的,5是3的左子树结点,故也是二叉树里3的左结点,6、7与5并列,就作为5的右子节点,类似的,4号结点也是一样,我们看图:
我们按照这句话,就能轻而易举的画出个大概了,然后我们把黑色的线抹去就行了。抹去之后,就成这样了:
这就验证了我的那句话一点问题都没有。千万不能着急,那么事情就没有想象的那么复杂了。
查找二叉树:
我们边看图边分析:
分析查找二叉树的一些递归条件:
a.查找树的左、右子树各是一颗查找树。这个很明了,无可厚非。
b.若查找树的左子树非空,则其左子树上的各节点均小于根结点的值。如图:2和4都小于5。
c.若查找树的右子树非空,则其右子树上的各节点值均大于根节点的值。如图:6和8都大于5。
所以结合图来分析问题,一切的理论都是浮云。记是记不住的。必须要理解。
我们有了这些对查找二叉树的认识之后,后面分析起来就简单了。
查找二叉树的一些基本操作:查找、插入结点、删除结点:
查找:
比如我们要查找56,那么我们就能马上找到,因为左结点的都比根节点要小,右结点都比根结点要大。所以我们很easy的找到了。
插入结点:
插入结点就有意思了,但是还是很简单,一样的规则,左小右大。继续前行:举个例子,插入29:从上面的图,我们一眼就看的出来,29必须要跟着20了,因为56的右结点要比56要大,所以不可能,那么112的左结点呢?更不可能了,因为112的所有子结点都要比根节点89要大,所以非常easy吧。只能作为20的右子结点了。
删除结点:
要是叶子结点就直接删除,要是带一个叶子结点的就直接吧叶子结点接到待删除的父结点上,要是带两个子节点的,就用中序遍历查找最大的结点,直接删除最大结点。
哈夫曼树:
我们看图理解:
树的路径长度:树到达每一个结点都有一个路径,把所有的路径的值加起来,路径长度之和,就是树的路径长度了。
就第一棵树来说:看图:
结点8的路径长度是3;2的路径长度是2,4的路径长度:3。兄弟结点的路径长度是一样的。
和结点数是息息相关的,同样结点的树,完全二叉树的路径长度是最短的。
权:对某个结点赋予一个有意义的值,其实就是我们看到的这些值,如叶子结点的权值是:2、4、8、1。
带权路径长度:权值乘以路径长度,比如叶子结点8的带权路径长度为:8*3=24。
树的带权路径长度:所有带权路径长度的值相加。哈夫曼树是一种带权路径长度最短的。比如第二颗树:
结果为:1*8+2*4+3*3=25
左边的是:
结果是:1*1+2*2+(4+8)*3=41,同样结构,同样结点数,机器运算所要花费的时间就不同,哈夫曼树是最优的。
如何构造哈夫曼树:
比如我们有一组权值{5,29,7,8,14,23,3,11}:
我们从最小的开始,最小的作为叶子结点,至于为什么,因为权值代表遍历的次数,所以我们考虑效率的问题,把权值最小的作为叶子结点,一颗颗树来拼接起来就OK了。
第一步我们就得到了:
哈夫曼树也是二叉树,所以也是按照二叉树的规则,左小右大。
继续一个一个把这些权值添加到这两颗树上面,从小到大的“堆积”起来,最后形成的大树。看图:
哈夫曼编码:左边为1,右边为1;把权标志了,比如23的编码是:00。11的编码是:010。看图:
就这么简单,所有结点的编码都出来了。
线索二叉树:
线索二叉树我们来讲讲怎么把二叉树装换成线索二叉树。
我们看这颗二叉树:
前序线索二叉树:
我们应该是怎么个步骤呢?我们先写出这颗二叉树的前序遍历:ABDEHCFGI,然后我们把结点的指针给填满,主要是找到叶子结点的前驱和后继。
我们从前序遍历ABDEHFCGI就能看出D结点的前驱结点是B结点,后继结点是E结点,类似的,把这些结点的空指针填满。,应该是这么个图:
中序线索二叉树,我们把中序二叉树遍历写出来:DBHEAFCGI;那么我们的中序线索二叉树就轻而易举的画出来了,看图:
后序线索二叉树,我们把后序二叉树遍历写出来:DHEBFIGCA;那么我们的后序线索二叉树就轻而易举的画出来了,看图:
线索二叉树的其他内容还有很多,用到的时候再说吧,线索二叉树与二叉树的转换,应该是大家需要的吧。
平衡二叉树:
1、或者是一颗空树;
2、或者是一颗:书中的任一结点的左、右子树的深度相差不超过1。我们分析一棵树:
我们凭感觉就知道这棵树不是平衡二叉树,一边倒,聪明:我们分析看看符合平衡二叉树的条件不:
在分析的过程中,我们把每一个结点当做是一棵树,如结点1当做空一棵树的时候,就是一颗空子树;结点5没有右子树,所以相差为1。,还有我们分析到结点39的时候,我们一看就知道它没有右子树,而左子树是3,可以把1、5、7作为左子树来判断。
所以这棵树是不符合我们的平衡二叉树的要求的。
我们来分析一颗符合要求的,看看符合要求的二叉树是什么样的:
其实我们用肉眼就能大概辨别的出来,但是要是信心不够的话,可以分析分析。
平衡树的调整:你懂了几个旋转就搞定了。看看这个旋转是什么个情况:
LL型平衡旋转:右旋平衡处理,其实就是想办法把这些二叉树弄平衡,看图:
RR型平衡旋转:左旋处理。
从上面的两个旋转来看,主要是把中间的那个节点作为根结点,然后另外两个结点分别作为左、右子树,就能达到目的。
接下来我们看有点点复杂的,其实也很简单:
LR型平衡旋转:我们有了上面两个基础,再来看这个也就easy了:看图说话:
不要被这个图吓着,其实我当时一看也懵了半天,但是经过我们一分析,都是纸老虎:我们看
1、我们把左边这个图分解来看:
左子树是添加了一个新的结点,一看很熟悉,我们把这颗左子树去掉BL和CL,那么就跟RR型旋转是一样的道理了,把C结点作为根结点,就成了:那么这边这棵树就没问题了,接下来我们看整棵树:
整棵树还是不平衡的,所以我们还是老办法,看成是LL型的:就能得到结果了:
还有一种旋转LR旋转,一样的,我们就不说了。呵呵,希望能帮到大家。