1,如何确定一颗二叉树(唯一)???
2,二叉树度的问题(叶子节点与度为2的节点加1)???
3,二叉排序树的插入,删除,简单理解
4,平衡二叉树的构建过程,,,,
扩充二叉树:
扩充二叉树是二叉树的一种,也叫扩展二叉树,是指在二叉树中出现空子树的位置增加空树叶所形成的二叉树、
、也就是空指针引出一个虚节点。。。。。其值为一特定值。。。
1,二叉树的一些基本特性
1,每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。注意不是只有两颗子树,而是最多有。
没有子树或者有一颗子树都是可以的。
2,在一个确定,唯一的二叉树中,左子树,右子树都是确定的,也就是说都是有顺序的,次序是不能颠倒的
3,即使树中只有一颗子树,也要区分它是左子树还是右子树,如下,它们就是不同的二叉树
简单的来说具有5中形态
1,空二叉树
2,只有一个跟结点
3,根结点只有左子树
4,根结点只有右子树
5,根结点有左右子树
一些奇怪的二叉树:
1,斜树,也就是说:二叉树从整体来看是斜的,所有的结点都只有左子树的叫左斜树,所有的结点都只有右子树
的叫做右斜树,有人说:这不就跟线性表差不多了吗???对,其实,线性表就是一个特殊的二叉树
可以很直观的看到:斜树的个数就是二叉树深度
2,满二叉树
对于二叉树而言,所有的叶子结点都在同一层并且都在最下层,其他的非叶子节点(每一个都有自己的左右孩
子),也就是说二叉树中,n层的话,那么节点数就是2^n - 1.
如下:
3,最优二叉树
若设二叉树的深度为h,除第h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层出现的节点,也都是从
左往右,不会说是出现右边的没有左边的
好啦,上面我们了解了二叉树的一些基本特性,下面我们来看一些问题
2,唯一确定的二叉树
问题1:
如何确定一个唯一的二叉树,结构,形态等都是唯一的???
1,可以通过先序遍历吗??
比如:存储的是A-B-C
可以确定的是:如果A-B-C存储的话,那么我们并不知道它具体是那一种的,如上,我们通过先序的遍历
并不能确定具体的形态,所以说,先序并不能确定唯一的二叉树
2,可以通过中序遍历吗??
可以知道:中序遍历上面两颗二叉树得到的结果也是一样的
3,可以通过后序吗??
如上图:也是不可以的,后序遍历的结果都是A-B
4,那么到这里,我们是如何确定一个稳定的唯一确定的二叉树呢???
能不能将上面的任意两种序列结合起来呢???比如:(先序加中序)
1,试试(先序加中序)
为了不影响结果的正确性,我们先设计一个确定的二叉树(如下),写出它的先序和中序,然后
在将其还原成一个二叉树
二叉树如上:
先序遍历:ABCDEF
中序遍历:BCAEDF
分析过程:从先序我们可以知道第一个A一定是当前二叉树的根节点,同时结合中序(左中右),可
以知道BC一定在A的左边,也就是说是A的左孩子那边的,那么EDF就一定是A右孩子那边的;
继续从先序得知下一个是B,可以知道在BC之间,B一定是A的直接左孩子,同时结合中序的序列
BC可知,C一定是B的右孩子;
所以A的左孩子这边就是:
同样的分析过程:EDF位于A根节点的右子树,结合先序可知:A的第一个直接右孩子是D,同时
因为在中序里面,先访问E,返回才访问D,最后是F,所以可以知道A这边右子树就是:
所以整合到一起就是:上面给出的那个完整的二叉树
5,那么可以通过中序加后序吗???先序加后序呢???
如同上面的分析过程,中序加后序也是一定可以确定一颗唯一的二叉树的
但是,对于先序加后序而言,,,就不能确定唯一一颗二叉树了,
如下结构:
不管是先序还是后序,但是它们的结构就是不一样
那么有的同学可能就会说了,这不对啊,我们平时创建不是这样子的啊,我们平时的创建并不会是类似于这样
确定一个先序和中序然后再去按照一定的算法去创建一个合理的二叉树,我们平时都是按照二叉树的先序建立
,好像是可以建立的吧,,,,
是吗????
好像的吧,,,哈哈,看,回答的也不是很确定了
其实是这样的,我们平时的创建方式是:采用扩充二叉树的先序方式来建立一颗唯一的二叉树的,关于扩充二叉
树,我们前面提到了,例如:我们来建立这样一颗二叉树的话:
那么我们的输入方式就是这样的:AB#C##DE##F##,所以说,我们当前所创建的二叉树是唯一确定的
所以在这里总结一下:要建立一颗唯一确定的二叉树,那么有一下方式:
(先序+中序),(中序+后序),(扩充先序二叉树)
树、森林和二叉树的转换
树转换为二叉树
(1)加线。在所有兄弟结点之间加一条连线。
(2)去线。树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线。
(3)层次调整。以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子)
森林转换为二叉树
(1)把每棵树转换为二叉树。
(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来。
二叉树转换为树
是树转换为二叉树的逆过程。
(1)加线。若某结点X的左孩子结点存在,则将这个左孩子的右孩子结点、右孩子的右孩子结点、右孩子的右孩子的右孩子结点…,都作为结点X的孩子。将结点X与这些右孩子结点用线连接起来。
(2)去线。删除原二叉树中所有结点与其右孩子结点的连线。
(3)层次调整。
二叉树转换为森林
假如一棵二叉树的根节点有右孩子,则这棵二叉树能够转换为森林,否则将转换为一棵树。
(1)从根节点开始,若右孩子存在,则把与右孩子结点的连线删除。再查看分离后的二叉树,若其根节点的右孩子存在,则连线删除…。直到所有这些根节点与右孩子的连线都删除为止。
(2)将每棵分离后的二叉树转换为树。
2,关于二叉树度的问题(面试经常会遇到)
设树T的度为4(例外,非二叉树),其中度为1,2,3,4的节点个数分别是4,2,1,1,那么
T中的叶子树为???
分析:一条边有两个结点,两条边有三个节点,所以
条边 = 结点 - 1
度为4:边为4; 度为3:边为3; 度为2:边为2; 度为1:变为1
所以,总的边数是:n = 4 × 1 + 3 × 1 + 2 × 2 + 1×4 = 15
所以,总的结点就是:16
叶子节点 = 16 - 度不为0的结点(4+2+1+1) = 8
关于二叉树的度
二叉树的度,只有0,1,2三种情况,度为0(叶子节点)度为1(只有一个孩子)度为2(一定有两个孩子)
首先先说一个结论:度为0的节点(叶子结点)是度为2的数量加1
证明:一个二叉树,共有结点N,二度结点为X,一度结点为Y,求叶子节点的个数(设为Z)??
N个结点总共N - 1条边,一度节点一条边,二度节点二条边,叶子节点0跳边
2X + Y = N - 1
X + Y + Z = N
好啦,两者联合求得: Z = X + 1;(哈哈,小时候的解方程这里用到了)
为了证明其合理行:我们先给出一颗二叉树(为了便于理解,二叉树很奇怪)
问题:一颗二叉树,度为1的结点数为4,度为2的节点树为4,那么该二叉树的叶子结点是多少呢,
总结点呢???
根据上面的这个结论,那么叶子节点就是5(度为2的个数加1)
总节点是:度为1 + 度为2 + 度为0 = 13
我们用上面的二叉树验证,完全正确
#include<stdio.h>
#include <malloc.h>
#include <conio.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node *LC