结点:结点不仅包含数据元素,而且包含指向子树的分支
非终端结点:又叫分支结点,指 度不为0的结点。 除了根结点之外的非终端结点,也叫作内部结点。
兄弟:同一双亲的孩子之间互为兄弟
堂兄弟:双亲在同一层的结点互为堂兄弟
树的高度(或者深度):树中结点的最大层数
结点的深度和高度:
1.结点的深度是从根结点到该结点路径上的结点个数
2.从某结点往下走可能到达多个叶子结点,其中最长的那条路径的长度即为该结点在树中的高度
3.根结点的高度为树的高度
森林:若干棵互不相交的树的集合。
树的顺序存储结构:双亲存储结构(用一维数组即可实现)
用数组下标表示树中的结点,数组元素的内容表示该结点的双亲结点。
树的链式存储结构
1.孩子存储结构
2.孩子兄弟存储结构
满二叉树:所有的分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下一层
完全二叉树:对一棵深度为k、有n个结点的二叉树进行编号后,各结点的编号与深度为k的满二叉树中相同位置航啊的结点的编号均相同。
通俗讲就是一棵完全二叉树一定是有一棵满二叉树从右至左 从上至下,依次删除结点所得到的。
二叉树的主要性质:
性质1 非空二叉树上叶子结点数等于双分支结点数加 1
总结点数=
总分支数=
总分支数=总结点数-1 (这一条结论对于任何树都适用,不仅仅针对二叉树)
由此可得: 化简得:
性质2 二叉树的 第i层上最多有(i≥1)个结点。
结点最多的情况即为满二叉树的情况,此时二叉树每层上的结点数构成了一个首项为1、公比为2的等比数列。 通项为,i为层数。
性质3 高度(或深度)为k的二叉树最多有(k≥1)个结点(其实质为等比数列前k项和的问题)
性质4 有n个结点的完全二叉树,对各结点从上到下、从左至右依次编号(编号范围为1~n),则结点之间有一下关系:
(若i为某结点a的编号)则:
如果i≠1,则a双亲结点的编号为
如果2i≤n,则a左孩子的编号为2i;如果2i>n,则a无左孩子。
如果2i+1≤n,则a的右孩子的编号为2i+1;如果2i+1>n,则a无右孩子。
性质5 函数Catalan():给定n个结点,能构成h(n)种不同的二叉树,
性质6 具有n(n≥1)个结点的完全二叉树的高度(或深度)
由性质3, <n≤
又可写为 ≤n<
对其取对数得:
由于h为整数,因此对 向下取整即得到一个等式:
二叉树的存储结构
1.顺序存储结构
即用一个数组来存储一棵二叉树(最适合于完全二叉树,用于存储一般二叉树会浪费大量的存储空间)
2.链式存储结构
结点类型定义如下:
typedef struct BTNode
{
char data;
struct BTNode *lchild;
struct BTNode *rchild;
}BTNode;
二叉树的遍历算法
1.先序遍历
如果二叉树为空树,则什么都不做;否则:
1)访问根结点;2)先序遍历左子树;3)先序遍历右子树
void preorder(BTNode *p)
{
if(p!=NULL)
{
Visit(p);
preorder(p->lchild);
preorder(p->rchild);
}
}
2.中序遍历
如果二叉树为空树,则什么都不做;否则:
1)中序遍历左子树;2)访问根结点;3)中序遍历右子树
void inorder(BTNode *p)
{
if(p!=NULL)
{
inorder(p->lchild);
Visit(p);
inorder(p->rchild);
}
}
3.后序遍历
如果二叉树为空树,则什么都不做;否则:
1)后序遍历左子树;2)后序遍历右子树;3)访问根结点
void postorder(BTNode *p)
{
if(p!=NULL)
{
postorder(p->lchild);
postorder(p->rchild);
Visit(p);
}
}