表达式(a-(b+c))*(d/e)存储在图下的一颗二叉树当中(二叉树的data域中是字符型)。编写程序求出该表达式。
做此题之前,可以在我上一篇文章里面,把素材复制过来。
我们先写一个运算函数,方便下面使用(该代码曾出现在 09.顺序栈和链栈的应用~ 中)
int operation(int a, char op, int b) {
if (op == '+') return a + b;
if (op == '-') return a - b;
if (op == '*') return a * b;
if (op == '/') {
//被除数不能为0!
if (b == 0) {
printf("error");
return 0;
}
else {
return a / b;
}
}
}
int comp(Tree *p) {
int A, B;
if (p != NULL) {
//如果说这个结点,它的左子树和右子树都不是空。那么就用后序遍历求值
if (p ->left != NULL && p->right != NULL) {
//后序遍历求出左子树的值,赋值给A
A = comp(p->left);
//后序遍历求出右子树的值,赋值给B
B = comp(p->right);
//返回运算结果
return operation(A, p->data,B);
}
else {
//如果当前左右子树为空,则为数值,直接返回
return p->data - '0';
}
}
else {
//如果是空树,直接返回-1
return -1;
}
}
int main(int argc, char* argv[]) {
//根据图中的样式构建一颗二叉树
//设A = 3,B=4,C=5,D=6,E=2
char A = '3', B = '4', C = '5', D = '6', E = '2';
Tree* tree = (Tree*)malloc(sizeof(Tree));
tree = getTree('*');
tree->left = getTree('-');
tree->left->left = getTree(A);
tree->left->right = getTree('+');
tree->left->right->left = getTree(B);
tree->left->right->right = getTree(C);
tree->right = getTree('/');
tree->right->left = getTree(D);
tree->right->right = getTree(E);
//开始运算
int n = comp(tree);
//测试是否成功
printf("(3-(4+5))*(6/2) = %d\n", (3 - (4 + 5)) * (6 / 2));
printf("二叉树的遍历运算为: %d",n);
getchar();
return 0;
}
如果有一棵二叉树,左子树的深度为L,右子树的深度为R。那么整棵树的深度就是max(L,R)+1。也就是左子树和右子树的深度中,谁最大,就让谁+1。所以说,我们只需要先求出左子树的深度,再求出右子树的深度,再套上那个公式就行了~
int getTreeDepth(Tree *p) {
//分别标识左右子树的深度
int L, R;
if (p == NULL) {
//如果是空树,那就肯定是0了
return 0;
}
else {
//求左子树的深度
L = getTreeDepth(p->left);
R = getTreeDepth(p->right);
//用最大的那个+1,便是了
return (L > R ? L : R) + 1;
}
}
因为题中二叉树各个结点data域的值没有任何规律,所以要判断是否存在data域值等于key的结点就必须把所有结点都访问一遍,挨个判断是不是等于key。所以这里又会用到二叉树的遍历方式来解决
//假设二叉树已存在并且tree指向其根结点
//这里p定义要是引用型指针,因为是需要改变的
void search(Tree *tree,Tree *&p,char key) {
//如果说这棵树是空树,那就什么都不做吧!
if (tree != NULL) {
//如果tree指的结点data域值等于key,那就将p指向域值等于key的结点
if (tree->data == key) {
p = tree;
}
else {
//在左子树查找
search(tree->left,p,key);
//在右子树查找
search(tree->right,p,key);
}
}
}
void findTreeNode(Tree *tree,int k) {
if (tree != NULL) {
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ",k,tree->data);
//退出程序
return;
}
findTreeNode(tree->left,k);
findTreeNode(tree->right, k);
}
}
//中序
void findTreeNodeMid(Tree* tree, int k) {
if (tree != NULL) {
findTreeNodeMid(tree->left, k);
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ", k, tree->data);
//退出程序
return;
}
findTreeNodeMid(tree->right, k);
}
}
//后序
void findTreeNodeLast(Tree* tree, int k) {
if (tree != NULL) {
findTreeNodeLast(tree->left, k);
findTreeNodeLast(tree->right, k);
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ", k, tree->data);
//退出程序
return;
}
}
}
#include
#include
typedef struct BinaryNode {
char data; //数据域
struct BinaryNode* left; //指针域 左孩子
struct BinaryNode* right; //指针域 右孩子
}Tree;
//赋值
Tree* getTree(char data) {
Tree* tree = (Tree*)malloc(sizeof(Tree));
tree->data = data;
tree->left = NULL;
tree->right = NULL;
return tree;
}
//先序遍历
void preOrder(Tree* root) {
if (root != NULL) {
printf("%c ", root->data);
preOrder(root->left);
preOrder(root->right);
}
}
//中序遍历
void inOrder(Tree* root) {
if (root != NULL) {
inOrder(root->left);
printf("%c ", root->data);
inOrder(root->right);
}
}
//后序遍历
void postOrder(Tree* root) {
if (root != NULL) {
postOrder(root->left);
postOrder(root->right);
printf("%c ", root->data);
}
}
//运算函数
int operation(int a, char op, int b) {
if (op == '+') return a + b;
if (op == '-') return a - b;
if (op == '*') return a * b;
if (op == '/') {
//被除数不能为0!
if (b == 0) {
printf("error");
return 0;
}
else {
return a / b;
}
}
}
int comp(Tree* p) {
int A, B;
if (p != NULL) {
//如果说这个结点,它的左子树和右子树都不是空。那么就用后序遍历求值
if (p->left != NULL && p->right != NULL) {
//后序遍历求出左子树的值,赋值给A
A = comp(p->left);
//后序遍历求出右子树的值,赋值给B
B = comp(p->right);
//返回运算结果
return operation(A, p->data, B);
}
else {
//如果当前左右子树为空,则为数值,直接返回
return p->data - '0';
}
}
else {
//如果是空树,直接返回-1
return -1;
}
}
//求二叉树的深度
int getTreeDepth(Tree* p) {
//分别标识左右子树的深度
int L, R;
if (p == NULL) {
//如果是空树,那就肯定是0了
return 0;
}
else {
//求左子树的深度
L = getTreeDepth(p->left);
R = getTreeDepth(p->right);
//用最大的那个+1,便是了
return (L > R ? L : R) + 1;
}
}
//假设二叉树已存在并且tree指向其根结点
//这里p定义要是引用型指针,因为是需要改变的
void search(Tree* tree, Tree*& p, char key) {
//如果说这棵树是空树,那就什么都不做吧!
if (tree != NULL) {
//如果tree指的结点data域值等于key,那就将p指向域值等于key的结点
if (tree->data == key) {
p = tree;
}
else {
//在左子树查找
search(tree->left, p, key);
//在右子树查找
search(tree->right, p, key);
}
}
}
//查找
int n = 0; //定义全局变量n,将结点计数初值为0
void findTreeNode(Tree* tree, int k) {
if (tree != NULL) {
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ", k, tree->data);
//退出程序
return;
}
findTreeNode(tree->left, k);
findTreeNode(tree->right, k);
}
}
//中序
void findTreeNodeMid(Tree* tree, int k) {
if (tree != NULL) {
findTreeNodeMid(tree->left, k);
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ", k, tree->data);
//退出程序
return;
}
findTreeNodeMid(tree->right, k);
}
}
//后序
void findTreeNodeLast(Tree* tree, int k) {
if (tree != NULL) {
findTreeNodeLast(tree->left, k);
findTreeNodeLast(tree->right, k);
++n;
if (k == n) {
//如果是,则输出
printf("第 %d 个结点是 %c ", k, tree->data);
//退出程序
return;
}
}
}
int main(int argc, char* argv[]) {
//根据图中的样式构建一颗二叉树
//设A = 3,B=4,C=5,D=6,E=2
char A = '3', B = '4', C = '5', D = '6', E = '2';
Tree* tree = (Tree*)malloc(sizeof(Tree));
tree = getTree('*');
tree->left = getTree('-');
tree->left->left = getTree(A);
tree->left->right = getTree('+');
tree->left->right->left = getTree(B);
tree->left->right->right = getTree(C);
tree->right = getTree('/');
tree->right->left = getTree(D);
tree->right->right = getTree(E);
//开始运算
int no = comp(tree);
//测试是否成功
printf("(3-(4+5))*(6/2) = %d\n", (3 - (4 + 5)) * (6 / 2));
printf("二叉树的遍历运算为: %d\n", no);
int max = getTreeDepth(tree);
printf("此二叉树的深度为: %d\n", max);
//进行查找,这里的p是用来引用的
char key = '/';
Tree* p = (Tree*)malloc(sizeof(Tree));
search(tree, p, key);
printf("key = %c\n", p->data);
//案例4
printf("先序遍历二叉树的结果: "); preOrder(tree); printf("\n");
findTreeNode(tree, 6); printf("\n");
//中序(案例4)
//全局变量归0
n = 0;
printf("中序遍历二叉树的结果: "); inOrder(tree); printf("\n");
findTreeNodeMid(tree, 6); printf("\n");
//后续(案例4)
//全局变量归0
n = 0;
printf("后序遍历二叉树的结果: "); postOrder(tree); printf("\n");
findTreeNodeLast(tree, 6);
getchar();
return 0;
}