二叉树的基本性质
性质1 二叉树第i层上至多有个结点(i>=1)
性质2 深度为k的二叉树至多有个结点(k>=1)
性质3 对于任何一颗二叉树T,如果其终端结点数为,度为2的结点数为
,
=
+1。由于二叉树中的结点的度小于等于2,所以结点的度为:
由于结点数=分支数+1,分支是由结点度为1或2的结点分支出来的,度为1的结点分支出一个分支,度为2的结点分支出2个分支,所以可得
联立可得
性质4 具有n个结点的完全二叉树深度为
性质5 如果对一棵有n个结点的完全二叉树(其深度为 )的结点编号(从第一层到最后一层每层从左到右),则对任意结点
(1)如果i=1,则结点i为二叉树的根,无双亲,则双亲的parent是结点;
如果2i>n,则结点i无左孩子;否则左孩子是结点2i;
(3)如果2i+1>n,则结点i无右孩子,否则右孩子是结点2i+1;
性质6 含有n个结点的二叉链表中,有2n个指针域,其中n-1个为非空指针域,n+1个为空指针域
二叉树的基本操作(链式存储)
二叉树的存储结构
# define MAX_TREE_SIZE 100
typedef TElemType SqBiTree[MAX_TREE_SIZE]
SqBiTree bt;
typedef struct BiTNode{
TElemType data;
struct BiTNode *rchild ,*lchild;
}BiTNode, *BiTree;
先序遍历创建二叉树
CreatBiTree(BiTree *T){
char ch;
scanf("%c",&ch);
if(ch=="*"){
*T=NULL;
return 0;
}else{
BiTNode *T=(*BiTNode)malloc(sizeof(BiTNode));
*T->rchild=NULL;
*T->lchild=NULL;
*T->data=ch; //对每个结点进行赋值
CreatBiTree((*T)->rchild); //递归调用函数,进入二叉树的右子树分支,直到右子树遍历完
CreatBiTree((*T)->lchild); //递归调用函数,进入二叉树的左子树分支,直到左子树遍历完
}
return 1;
}
二叉树前序遍历
//最简单的Visit函数是:
Status PrintElement(TElemType e){
printf("%d",e);
Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e)){
//采用二叉链表存储结构,Visit是对数据元素操作的应用函数,
//先序遍历二叉树T的递归算法,对每个递归函数调用函数Visit
if(T){
if(Visit(T->data){
if(PreOrderTraverse(T->lchild,Visit)){
if(PreOrderTraverse(T->rchild,Visit)){
return OK;
}
return ERROR;
}else return OK;
}
二叉树中序遍历
//最简单的Visit函数是:
Status PrintElement(TElemType e){
printf("%d",e);
Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e)){
//采用二叉链表存储结构,Visit是对数据元素操作的应用函数,
//中序遍历二叉树T的递归算法,对每个递归函数调用函数Visit
if(T){
if(PreOrderTraverse(T->lchild,Visit)){
if(Visit(T->data){
if(PreOrderTraverse(T->rchild,Visit)){
return OK;
}
return ERROR;
}else return OK;
}
二叉树后序遍历
//最简单的Visit函数是:
Status PrintElement(TElemType e){
printf("%d",e);
Status PreOrderTraverse(BiTree T,Status (*Visit)(TElemType e)){
//采用二叉链表存储结构,Visit是对数据元素操作的应用函数,
//后序遍历二叉树T的递归算法,对每个递归函数调用函数Visit
if(T){
if(PreOrderTraverse(T->lchild,Visit)){
if(PreOrderTraverse(T->rchild,Visit)){
if(Visit(T->data){
return OK;
}
return ERROR;
}else return OK;
}
二叉树前中后序遍历其实差别并不大,区别仅在于结点的访问顺序,先序遍历是先访问结点数据,然后再访问左结点,右节点;中序遍历是先访问左节点然后访问结点数据,最后访问右节点;后序遍历是先访问左节点,然后访问右节点,最后访问结点数据。