(1)题目:表达式(a-(b+c))*(d/e)存储在二叉树链表中,结点为char型,编写程序计算出该表达式的值(表达式中操作数为整数)
分析:后序遍历,先求左子树表达式的值,再求右子树表达式的值,然后就求两个结果的值。
代码:
typedef struct BTNode
{
char data; //默认为int型,或者写成 ElementType element
struct BTNode *lchild;
struct BTNode *rchild;
} BTNode; //二叉树结点定义
int compute(BTNode *p)
{
int A, B;
if ( NULL != p )
{
if (NULL != p->lchild && NULL != p->rchild ) //后序遍历
{
A = compute(p->lchild);
B = compute(p->rchild);
return operation(A,B,p->data);
}
else
{
return (p->data - '\0'); //左右子树为空,则为数值,直接返回
}
}
else
{
return 0; //空树,表达式的值为0
}
}
int operation(int a, int b, char c)
{
int temp = 0;
switch( c )
{
case '+':
temp = a + b;
break;
case '-':
temp = a - b;
break;
case '*':
temp = a * b;
break;
case '/':
temp = a / b;
break;
case '%':
temp = a % b;
break;
default:
break; //不够严谨,没有处理特殊情况
}
return temp;
}
(2)题目:设计算法求二叉树的深度,二叉树为二叉链表存储。
分析:若左子树深度为LD,右子树深度为RD,则整个树的深度为max{LD, RD} + 1 ,后序遍历
代码:
typedef struct BTNode
{
char data; //默认为int型,或者写成 ElementType element
struct BTNode *lchild;
struct BTNode *rchild;
} BTNode; //二叉树结点定义
int getDepth(BTNode *p)
{
int LD, RD;
if (NULL == p)
{
return 0; //空树,返回0
}
else
{
LD = getDepth(p->lchild); //左子树深度
RD = getDepth(p->rchild); //右子树深度
return (LD > RD ? LD : RD) + 1 ; //整棵树的深度
}
}
(3)题目:二叉链表存储的二叉树中,查找data为key的结点是否存在(找到任何一个满足要求的结点即可),若存在,将q指向该结点,否则q赋值为NULL
分析:二叉树遍历,逐一判断。
代码:
typedef struct BTNode
{
char data; //默认为int型,或者写成 ElementType element
struct BTNode *lchild;
struct BTNode *rchild;
} BTNode; //二叉树结点定义
void search( BTNode *p, BTNode *&q, char key) //将参数q定义为引用指针型,因为q要改变
{
if ( NULL != p ) //
{
if ( key == p->data) //如果是字符串数据,则使用strcmp()函数
{
q = p ; //若是找到,则赋值
}
else
{
search(p->lchild, q, key); //到左子树中查找
search(p->rchild, q, key); //到右子树中查找
/*********************************************/
/* 改进建议如下:如果在左子树中没找到,再到右子树中查找*/
// search(p->lchild, q, key); //到左子树中查找
// if ( NULL == q )
// {
// search(p->rchild, q, key); //到右子树中查找
// }
/********************************************/
}
}
/* 如果是空树,则什么也不用做,保持 q = NULL */
}
补充:在二叉树的前、中、后三种遍历中的 前和中,中和后 两对遍历序列都可以唯一确定这棵二叉树,根据 前和后,则不能确定。
题目(4):二叉树链表存储,编写算法,输出先序遍历中,第k个结点的值。(k不大于总结点数,data为char型)
分析:添加判断代码,确定指针p第一次经过该节点时的操作
代码:
int ncount = 0; //定义全局变量nCount,将结点计数初值设为0
void trave(BTNode *p, int k)
{
if ( NULL != p )
{
++ ncount ;
if ( k == ncount ) //当第一次来到这个结点的时候,判断这个结点是否是先序序列中的第k个结点
{
cout << p->data << endl; //如果是,则输出;并且无需遍历,使用return直接返回
return;
}
trave(p->lchild, k);
trave(p->rchild, k);
}
}
//改为中序,如下
void trave(BTNode *p, int k)
{
if ( NULL != p )
{
trave(p->lchild, k);
++ ncount ;
if ( k == ncount ) //当第一次来到这个结点的时候,判断这个结点是否是中序序列中的第k个结点
{
cout << p->data << endl; //如果是,则输出;并且无需遍历,使用return直接返回
return;
}
trave(p->rchild, k);
}
}