上周二叉树的实验报告拖到今天才勉强完成,说明对二叉树的掌握还不是很透彻,在递归算法上没怎么弄清楚,下面记录写出的几个二叉树的基本操作:
1.构建二叉树
2.求二叉树的叶子数
3.求二叉树的深度
构建二叉树时需要注意的地方:
计算树的深度:
总结:二叉树的操作很大程度上用到了递归的思想,对递归的用法和对指针的理解仍需要加强。
1.构建二叉树
2.求二叉树的叶子数
3.求二叉树的深度
这里采用的是二叉树的链式存储:
typedef struct BiTNode{
TElemType data;
struct BiTNode *lchild,*rchild;//左右孩子指针
}BiTNode ,*BiTree;
二叉树的构建主要思路采用递归思想(求叶子数和求深度都用到了递归的思想):如果输入的不是标记符,则开始构建左子树和右子树,否则就将该结点data值记为标记符
int CreateBiTree(BiTree *T)
{
char ch;
printf("\n\t\t\t\t\t ch:");
fflush(stdin);
scanf("%c",&ch);
if(ch == 'Z')
{
if(!(*T = (BiTNode *)malloc(sizeof(BiTNode))))//!!!very important!!!
{
exit(OVERFLOW);
}
(*T)->data = ch;
}
else
{
if(!(*T = (BiTNode *)malloc(sizeof(BiTNode))))
{
exit(OVERFLOW);
}
printf("\t\t\t\t\t(*T)->data = ch:");
(*T)->data = ch; //生成根节点
printf(" lchild:");
CreateBiTree(&(*T)->lchild); //生成左子树
printf("\t\t\t\t\t rchild:");
CreateBiTree(&(*T)->rchild); //生成右子树
}
return OK;
}//创建二叉树
构建二叉树时需要注意的地方:
一开始写成了
if(ch == 'Z')
{
(*T)->data = ch;
}
写了一个野指针,没有为其分配空间,导致给二叉树赋值的时候非正常退出,应为:
if(ch == 'Z')
{
if(!(*T = (BiTNode *)malloc(sizeof(BiTNode))))//!!!very important!!!
{
exit(OVERFLOW);
}
(*T)->data = ch;
}
计算叶子数思想:判断该结点data值是否是标记符,如果是则返回0,如果不是则判断左右子树是否均为空,即判断该结点是否为叶子结点,如果是则返回1,如果该节点左右子树不为空,则分别计算左右子树的叶子结点然后相加
int CountBiTreeLeaf(BiTree T)
{
if(T->data == 'Z')
{
return 0;
}
else if((T->lchild->data == 'Z') && (T->rchild->data == 'Z'))
{
return 1;
}
else
{
return CountBiTreeLeaf(T->lchild) + CountBiTreeLeaf(T->rchild);
}
}//统计叶子结点的个数
计算树的深度:
1、基准情形:空树返回0;
2、递归形式:若不是空树,比较它的左子树深度和
右子树深度,返回较大深度值加1,即:
return (rightdep>leftdep) ? rightdep+1 : leftdep+1;
int BiTreeDepth(BiTree T)
{
/**1、基准情形:空树返回0;
2、递归形式:若不是空树,比较它的左子树深度和
右子树深度,返回较大深度值加1,即:
return (rightdep>leftdep) ? rightdep+1 : leftdep+1;
**/
int LeftBiTreeDepth = 0;
int RightBiTreeDepth = 0;
if(T->data == 'Z')
{
return 0;
}
else
{
LeftBiTreeDepth = BiTreeDepth(T->lchild);
RightBiTreeDepth = BiTreeDepth(T->rchild);
return (LeftBiTreeDepth > RightBiTreeDepth) ? LeftBiTreeDepth + 1 :RightBiTreeDepth + 1;
}
}//求树的深度
总结:二叉树的操作很大程度上用到了递归的思想,对递归的用法和对指针的理解仍需要加强。