1.树的定义
每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树
2.度
结点拥有的子树数称为结点的度,度为0的结点称为叶结点或终端结点;度不为0的结点称为非终端结点或分支结点,除根结点外分支结点也称为内部结点。树的度是树内各结点度的最大值。
3.结点间的关系
双亲、孩子、兄弟
4.树中结点的最大层次称为树的深度或高度
5.树的存储结构
(1)双亲表示法:在每个节点中除了标记自己的值外还要标记自己的双亲的位置。
还可以记录自己兄弟的位置
(2)孩子表示法:每一个节点有多个指针域,每一个指针域指向一棵子树的根结点。
方案一:指针域的个数等于树的度。
方案二:每个节点指针域的个数等于该节点的度,再取一个位置专门存储度的个数。
改进:
将每个节点的孩子节点排列起来,以单链表做存储结构,则n个节点有那个孩子链表,如果是叶子节点,则此链表为空,然后n个头指针构成一个线性表,采用顺序存储结构,放置到一个数组中。
(3)孩子兄弟表示法
任意一棵树,她的结点的第一个孩子如果存在就是唯一的,他的右兄弟如果存在也是唯一的。因此我们设置两个两个指针分别指向该结点的第一个孩子和此结点的右兄弟。这样排列好后,就排列成了一个二叉树。
6.二叉树
二叉树是n个结点的有限集合,该集合或者为空集,或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
特点:
(1)每个结点最多有两棵子树
(2)左子树跟右子树是有顺序的
(3)即使树中某结点只有一棵子树,也要区分它是左子树还是右子树
7.特殊二叉树
(1)斜树
所有的结点都只有左子树的二叉树叫左斜树,所有的结点都只有右子树的叫右斜树。
(2)满二叉树
所有的分支结点都存在左子树和右子树,并且所有的叶子都在同一层上。
(3)完全二叉树
只允许最后一层有空缺结点且空缺在右边,即叶子结点只能在层次最大的两层上出现。
8.二叉树的性质
性质1:在二叉树的第i层上至多有2i-1个结点
性质2:深度为K的二叉树至多有2K-1个结点
性质3:对任何二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 =n2+1
性质4:具有n个结点的完全二叉树的深度为log2n+1
性质5:
9.二叉树的存储结构
(1)顺序结构(一般用于完全二叉树)
(2)二叉链表
二叉树结点设计为一个数据域两个指针域构成,两个指针域分别存储该节点的两个孩子的位置。
10.二叉树的遍历
(1)前序遍历
先访问根结点,先遍历左子树,再遍历右子树。
void PreOrderTraverse(BiTree T)
{
If(T==NULL) return;
printf(“%c”,T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
(2)中序遍历
中序遍历根结点的左子树,访问根结点,再终须遍历右子树,遍历顺序我理解的应该是
左孩子->双亲->右孩子 而且这个顺序不能改变
void PreOrderTraverse(BiTree T)
{
If(T==NULL) return;
PreOrderTraverse(T->lchild);
printf(“%c”,T->data);
PreOrderTraverse(T->rchild);
}
(3)后序遍历
从左到右先叶子再结点的方式遍历访问左右子树
void PreOrderTraverse(BiTree T)
{
If(T==NULL) return;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
printf(“%c”,T->data);
}
(4)层序遍历
从树的第一层,也就是根结点开始,从上而下逐层遍历,在同一层中,按照从左到右的顺序
11.二叉树的建立