本段代码的功能包括:
1、用不同的前序遍历创建二叉树。
2、分别用递归或借助栈实现二叉树的前、中、后序遍历。
3、二叉树的深度、广度遍历。
4、判断一棵树是否是完全二叉树、满二叉树
5、用不同方法求所有根结点到树叶的路径、树叶到根结点的路径
6、求树的树宽、树深(树高)
7、求树的最长路径
8、输出所有叶子结点
9、计算二叉树零度、一度、二度结点的数量
10、将数的中缀表达式转化为后缀表达示,并求解树的中缀表达式
C++实现树的前中后序遍历、广度、深度优先遍历、求叶子结点、一度、二度结点数量、判断是否是完全、满二叉树、交换左右结点、求解所有根结点到树叶的路径、求最大宽度、高度、树深、求最长路径、输出所有叶子结点https://mp.csdn.net/mp_blog/creation/editor/121463277
#include#include #include #define OK 1 #define maxsize 100 using namespace std; //定义一棵树的结构体包括根结点、左孩子,右孩子(字符树) typedef struct Tnode { char data; string combine_data; //结点数据域(数值,可大于9),用于树的表达式求值 struct Tnode* lchild, * rchild; }*Btree; //数字树 typedef struct node { int data; struct node* lchild, * rchild; }*Bntree; void Instruct_char(Btree T); void Create_Tree(Btree T); void Calculate_Tree(Btree T); void Traverse(Btree T); void Estimate(Btree T); void Path(Btree T); void Calculate_Node(Btree T); void Swap_child(Btree T); void Build(Btree& T); void CreateTree(Btree& T, char ch[], int& index); int Tree_Width_recursion(Btree T); int Tree_Width(Btree T); int Tree_Depth_recursion(Btree T); int Tree_Depth(Btree T); void PreOrder(Btree T); void PreOrder_recursion(Btree T); void InOrder(Btree T); void InOrder_recursion(Btree T); void PostOrder(Btree T); void PostOrder_recursion(Btree T); void postOrder_visit(Btree T); void Breadth_First_Search(Btree T); void Depth_First_Search(Btree T); void Sequence_traverse(Btree T); void Depth_First_Search(Btree T); bool isComplete_Tree(Btree T); bool isFullBinaryTree(Btree T); void Every_path_recursion(Btree T, char E_path[], int len); void AllPath(Btree T); void All_path_root_leaf(Btree T, int pos); void One_Longest_Path(Btree T); void Find_First_Longest_Path(Btree T); void Print_First_Longest_Path(Btree T); void Sum_node(Btree T, int& zero, int& one, int& two); int getAllNode(Btree T); void PrintLeaves(Btree T); void swap(Btree& T1, Btree& T2); void Node_Swap(Btree& T); void Clear(); Btree Inquire_node(Btree T, char n); Bntree Create_Number_Tree(); void Instruct_number(); void CreateBiTree(Bntree* T); void Index(); void Func(); int main() { Btree T = nullptr; Bntree T1 = nullptr; Index(); return 0; } void Clear() { cin.clear(); cin.ignore(1, EOF); cout << endl; system("cls");//清屏函数 } void Index() { Btree T=nullptr; int choice = 0; cout << "请选择:n1、字符树n2、数字树n3、树的中缀表达式求值n"; while (cin >> choice && choice != 0) { switch (choice) { case 1:Instruct_char(T); break; case 2:Instruct_number(); break; case 3:Func(); break; default:cout << "输错啦,请重新输入..." << endl; } } } void Instruct_number() { Bntree T; int choice = 0; cout << "请选择:n1、“-1为空的树创建n2、以零为空的树的创建n3、返回主菜单n"; while (cin >> choice) { switch (choice) { case 1:Create_Number_Tree(); cout << "创建成功" << endl; Index(); case 2:CreateBiTree(&T); cout << "创建成功" << endl; Index(); case 3:Index(); break; default:cout << "输错啦,请重新输入..." << endl; } } } void Instruct_char(Btree T) { int choice = 0; Clear(); cout << "-------------------------欢迎来到树专题学习栏目-------------------n"; printf("请选择你想要的操作n1、创建二叉树n2、求树高树宽n3、遍历输出n4、关于树的判断n5、n6、路径查询n7、求解各种结点数量n8、交换左右孩子n、返回主菜单"); while (cin >> choice && choice != 0) { switch (choice) { case 1:Create_Tree(T); break; case 2:Calculate_Tree(T); break; case 3:Traverse(T); break; case 4:Estimate(T); break; case 6:Path(T); break; case 7:Calculate_Node(T); break; case 8:Swap_child(T); break; default:cout << "输错啦,请重新输入...n" << endl; break; } } Clear(); } void Create_Tree(Btree T) { int choice = 0; char ch[maxsize]; int index = 0; Clear(); printf("请选择您想要进行的操作n1、前序创建树之char数组法n2、直接用charn3、前序创建数字树(用-1区分是否为空)n4、创建数字树(用0区分是否为空)n"); while (cin >> choice && choice != 0) { cout << "请输入前序遍历的树字符串" << endl; switch (choice) { case 1: Build(T); cout << "创建成功" << endl; Instruct_char(T); case 2:CreateTree(T, ch, index); cout << "创建成功" << endl; Instruct_char(T); case 3: Create_Number_Tree(); cout << "创建成功" << endl; Instruct_char(T); default:cout << "输错了,请重新输入...n" << endl; break; } } } void Calculate_Tree(Btree T) { Clear(); int choice = 0; cout << "请选择:n1、求树宽n2、求树高n3、返回次级页面n4、返回主菜单n"; while (cin >> choice && choice != 0) { cout << "请继续输入选项" << endl; switch (choice) { case 1:cout << "递归求树宽:" << endl; cout << Tree_Width_recursion(T) << endl; cout << "层次遍历求树宽:" << endl; cout << Tree_Width(T) << endl; break; case 2:cout << "递归求树深:" << endl; cout << Tree_Depth_recursion(T) << endl; cout << "层次遍历求树深:" << endl; cout << Tree_Depth(T) << endl; break; case 3:Instruct_char(T); case 4:Index(); default:cout << "输错啦,请重新输入...n" << endl; break; } } } void Traverse(Btree T) { Clear(); int choice = 0; Clear(); printf("1、前序遍历n2、中序遍历n3、后序遍历n4、广度优先遍历n5、深度优先遍历n6、返回次级页面n7、返回主菜单n"); while (cin >> choice && choice != 0) { cout << "请输入选项..." << endl;; switch (choice) { case 1:cout << "前序递归遍历" << endl; PreOrder_recursion(T); cout << endl; cout << "前序非递归使用栈遍历" << endl; PreOrder(T); cout << endl; break; case 2:cout << "中序递归遍历" << endl; InOrder_recursion(T); cout << endl; cout << "中序非递归使用栈遍历" << endl; InOrder(T); cout << endl; break; case 3:cout << "后序递归遍历" << endl; PostOrder_recursion(T); cout << endl; cout << "后序非递归使用栈遍历" << endl; PostOrder(T); cout << endl; cout << "访问标记法结果为:" << endl; postOrder_visit(T); break; case 4:cout << "广度优先遍历结果为:" << endl; Breadth_First_Search(T); cout << endl; cout << "层序遍历结果为:" << endl; Sequence_traverse(T); cout << endl; break; case 5:cout << "深度优先搜索结果为:" << endl; Depth_First_Search(T); break; case 6:Instruct_char(T); case 7:Index(); default:cout << "输错啦,请重新输入..." << endl; break; } } } void Estimate(Btree T) { Clear(); int choice = 0; cout << "1、是否为完全二叉树n2、是否为满二叉树n3、返回次级页面n4、返回主菜单" << endl; while (cin >> choice && choice != 0) { cout << "请输入" << endl; switch (choice) { case 1:cout << "是否为完全二叉树" << " " << isComplete_Tree(T) << endl; break; case 2:cout << "是否为满二叉树" << " " << isFullBinaryTree(T) << endl; break; case 3:Instruct_char(T); case 4:Index(); default:cout << "输错啦,请重新输入..." << endl; break; } } } void Path(Btree T) { Clear(); int choice = 0; char E_path[maxsize]; int len = 0; int pos = 0; char data = '0'; cout << "请选择:1、所有叶子结点到根结点的路径n2、最长路径n3、查询结点n4、返回次级页面n5、返回主菜单n"; while (cin >> choice && choice != 0) { cout << "请输入..." << endl; switch (choice) { case 1:cout << "递归求所有叶子结点到根结点的路径" << endl; Every_path_recursion(T, E_path, len); cout << endl; cout << "非递归法" << endl; AllPath(T); break; cout << endl; cout << "从根结点开始到树叶的所有路径:" << endl; cout << "根结点到所有树叶的路径:" << endl; All_path_root_leaf(T, pos); cout << endl; break; case 2:cout << "其中一条最长路径:" << endl; One_Longest_Path(T); cout << endl; cout << "第一条最长路径:" << endl; Find_First_Longest_Path(T); Print_First_Longest_Path(T); cout << endl; break; case 3:cout << "输入您要查询的结点:" << endl; Inquire_node(T, data); cout << "查询结果" << Inquire_node(T, data) << endl; case 4:Instruct_char(T); case 5:Index(); default:cout << "输错啦,请重新输入" << endl; break; } } } void Calculate_Node(Btree T) { Clear(); int choice = 0; int zero = 0, one = 0, two = 0; cout << "请选择:n1、零度、一度、二度结点数量n2、所有叶子结点数量n3、输出所有树叶n4、返回次级页面n5、返回主菜单n"; while (cin >> choice && choice != 0) { switch (choice) { case 1:cout << "各种结点的数量" << endl; Sum_node(T, zero, one, two); cout << endl; break; case 2:cout << "所有结点的数量:" << endl; getAllNode(T); cout << endl; break; case 3:cout << "输出所有叶子结点:" << endl; PrintLeaves(T); cout << endl; break; case 4:Instruct_char(T); case 5:Index(); default:cout << "输错啦,请重新输入..." << endl; break; } } } void Swap_child(Btree T) { Clear(); int choice = 0; Btree T1 = nullptr; Btree T2 = nullptr; swap(T1, T2); Node_Swap(T); cout << "请选择:1、查看交换后的前序遍历结果n2、返回次级页面n3、返回主菜单" << endl; cin >> choice; while (choice) { switch (choice) { case 1:PreOrder_recursion(T); break; case 2:Instruct_char(T); case 3:Index(); default:cout << "输错啦,请重新输入..." << endl; break; } } } //前序遍历创建树char void Build(Btree& T) { char ch; cin >> ch; if (ch == '0') T = NULL; else { T = (Tnode*)malloc(sizeof(Tnode)); T->data = ch; Build(T->lchild); Build(T->rchild); } } //前序遍历创建树,使用char数组 void CreateTree(Btree& T, char chars[], int& i) { cin >> chars[i]; if (chars[i] == '0') { T = NULL; } else { T = new Tnode; T->data = chars[i]; CreateTree(T->lchild, chars, ++i); //递归构建左子树 CreateTree(T->rchild, chars, ++i); //递归构建右子树 } } Bntree Create_Number_Tree() { Bntree T; int data = 0; cin >> data; if (data == -1) T = NULL; else { T = new node; T->data = data; T->lchild = Create_Number_Tree(); T->rchild = Create_Number_Tree(); } return T; } void CreateBiTree(Bntree* T) { int data; scanf_s("%d", &data); if (data == 0) *T = NULL; else { *T = (Bntree)malloc(sizeof(node)); if (!*T) exit(1); (*T)->data = data; //生成根结点 CreateBiTree(&(*T)->lchild);//构造左子树 CreateBiTree(&(*T)->rchild);//构造右子树 } } //前序递归 遍历 void PreOrder_recursion(Btree T) { if (T != NULL) { cout << T->data << " "; PreOrder_recursion(T->lchild); PreOrder_recursion(T->rchild); } } //前序遍历非递归版本 //由于整个左子树被访问完才能访问右子树,故需要借助栈来保存当前子树的根节点 void PreOrder(Btree T) { stack S;//开辟一个栈 Btree p = T;//迭代指针 开始指向root while (p || !S.empty()) { //只要还有结点 if (p) { //如果当前结点不空 cout << p->data << " "; //则打印当前结点 因为是先序,遇到新结点就打印 S.push(p);//当前结点入栈 p = p->lchild;//访问其左子树,向左访问结点 } else { p = S.top();//如果当前结点是空的,就退回到上一个结点 S.pop();//退栈 p = p->rchild;//访问其右子树 } } } //中序递归 遍历 void InOrder_recursion(Btree T) { if (T != NULL) { InOrder_recursion(T->lchild); cout << T->data << " "; InOrder_recursion(T->rchild); } } //中序非递归遍历 左 中 右 //根节点必须在左结点访问之后再访问,而根节点又是先于左子节点被遍历到,故要设置一个栈来保存 void InOrder(Btree T) { stack S;//开辟一个栈 Btree p = T;//迭代器 while (p || !S.empty()) { //如果还有结点 if (p) {//如果当前结点不为空 S.push(p);// 不要急于访问根节点,先压栈。 p = p->lchild;//访问左子树 } else {//如果当前节点是空的。则需要退回到上一个结点 p = S.top(); S.pop();//退到该子树的根节点立即访问 cout << p->data << " "; p = p->rchild;//继续访问右子树 } } } //后序递归 遍历 void PostOrder_recursion(Btree T) { if (T != NULL) { PostOrder_recursion(T->lchild); PostOrder_recursion(T->rchild); cout << T->data << " "; } } //后序遍历非递归 双栈法 //由于是左 右 中,因此入栈次序是中右左, //先看根节点,再看右孩子,再看左孩子 void PostOrder(Btree T) { stack S; //遍历栈 stack result; //结果栈 Btree p = T;//迭代器 while (p || !S.empty()) { if (p) { //如果当前结点不为空 S.push(p);//结点入栈 result.push(p);//结点入结果栈 p = p->rchild;//看其右孩子结点 } else { //如果当前结点为空 ,退到上一个结点 p = S.top(); S.pop();//退栈 p = p->lchild;//找其左孩子结点 } } //输出后序序列 while (!result.empty()) { p = result.top(); result.pop(); cout << p->data << " "; } } // 后序遍历 访问标记法 void postOrder_visit(Btree T) { stack S; //开辟一个栈 Tnode* p = T; //迭代器 Tnode* r = NULL; //保存最近访问过的结点 while (p || !S.empty()) { if (p) { //如果当前结点不为空 则走到该子树的最左边 S.push(p); p = p->lchild; } else { //若为空,退到上一个结点 p = S.top(); if (p->rchild && p->rchild != r) { //如果存在右子树并且右子树没有被访问过 p = p->rchild;//那么就转向右子树继续 S.push(p); // 保存子树根节点 p = p->lchild; //继续向左访问左子树 } else { p = S.top(); S.pop();//没有右子树那就可以访问根节点了 cout << p->data << " "; r = p; //标记r为最近访问的结点 p = NULL; //当前结点置为空 ,因为这棵子树的根节点都访问完了说明这颗子树就全部访问完了,就等待退回上一个子树根节点 } } } } //层次遍历(广度遍历)求树宽度 //在层次遍历基础上。增加对每一层结点数的统计,维护max int Tree_Width(Btree T) { int level = 0; if (!T) return 0; queue Q; Tnode* last = T; //记录每层最后一个结点,第一层最后一个节点就是根节点 Tnode* front = nullptr, * rear = nullptr;//记录队首结点 队尾结点 int ans = 0;//记录最大宽度 int cur = 0;//记录当前层的宽度 Q.push(T);//根节点入队 while (!Q.empty()) { front = Q.front();//取队首 Q.pop();//队首弹出 cur++; if (front->lchild) { Q.push(front->lchild);//如果有左孩子那么左孩子入队 rear = front->lchild; } if (front->rchild) { Q.push(front->rchild);//如果有右孩子那么右孩子入队 rear = front->rchild; } if (front == last) {//如果当前结点是该层最后一个结点 //cout< data<<" ?? "< data< lchild, level + 1, count); Tree_Width_recursion(T->rchild, level + 1, count); } int Tree_Width_recursion(Btree T) { int count[200] = { 0 }; int maxx = 0; Tree_Width_recursion(T, 0, count); for (int i = 0; i < 200; i++) { maxx = max(maxx, count[i]); } return maxx; } //递归求树高 int Tree_Depth_recursion(Btree T) { if (T == NULL) return 0; int rightTree = Tree_Depth_recursion(T->rchild); int leftTree = Tree_Depth_recursion(T->lchild); return (rightTree > leftTree) ? (rightTree + 1) : (leftTree + 1); } int Depth(Btree T) { if (T == NULL) return 0; return 1 + (Depth(T->lchild) > Depth(T->rchild) ? Depth(T->lchild) : Depth(T->rchild)); //选择左右孩子深度高的然后加上根节点这一层就是深度了 } //层序(广度遍历)遍历求树高 int Tree_Depth(Btree T) { int level = 0; if (!T) return 0; queue Q; Tnode* last = T; //记录每层最后一个结点,第一层最后一个节点就是根节点 Tnode* front = nullptr, * rear = nullptr;//记录队首结点 队尾结点 Q.push(T);//根节点入队 while (!Q.empty()) { front = Q.front();//取队首 Q.pop();//队首弹出 if (front->lchild) { Q.push(front->lchild);//如果有左孩子那么左孩子入队 rear = front->lchild; } if (front->rchild) { Q.push(front->rchild);//如果有右孩子那么右孩子入队 rear = front->rchild; } if (front == last) {//如果当前结点是该层最后一个结点 //cout< data<<" ?? "< data< nodeStack; //使用C++的STL标准模板库 nodeStack.push(root); Tnode* node; while (!nodeStack.empty()) { node = nodeStack.top(); cout << node->data;//遍历根结点 nodeStack.pop(); if (node->rchild) { nodeStack.push(node->rchild); //先将右子树压栈 } if (node->lchild) { nodeStack.push(node->lchild); //再将左子树压栈 } } } //广度优先遍历 void Breadth_First_Search(Btree root) { queue nodeQueue; //使用C++的STL标准模板库 nodeQueue.push(root); Tnode* node; while (!nodeQueue.empty()) { node = nodeQueue.front(); nodeQueue.pop(); cout << node->data;//遍历根结点 if (node->lchild) { nodeQueue.push(node->lchild); //先将左子树入队 } if (node->rchild) { nodeQueue.push(node->rchild); //再将右子树入队 } } } //层序遍历 队列 void Sequence_traverse(Btree T) { queue Q; Tnode* p = T; Q.push(T); while (!Q.empty()) { p = Q.front(); Q.pop(); cout << p->data << " "; if (p->lchild) Q.push(p->lchild); if (p->rchild) Q.push(p->rchild); } } //判断时否是完全二叉树 //利用性质 完全二叉树与满二叉树在层次遍历上的联系和区别,前者是后者序列的一部分 bool isComplete_Tree(Btree T) { queue Q;//Q中存储层次遍历序列 Tnode* p; if (!T) return true;//空树也当成完全二叉树 它是满二叉树 Q.push(T);//首结点入队 while (!Q.empty()) { //如果Q不空 p = Q.front(); // 取出队首 Q.pop(); if (p) { //如果当前结点不空,将其左右孩子入队,不管孩子空不空 Q.push(p->lchild); Q.push(p->rchild); } else { //如果当前结点为空,那么之后的序列不能有不空的结点,因为层次遍历ABCD.E显然是非法的 while (!Q.empty()) { p = Q.front(); Q.pop(); if (p) return false; } } } return true; } bool isFullBinaryTree(Btree T) { if (T == NULL) return true; typedef std::pair PTI; //pair的第二个模版参数用于记录层数 queue q; q.push(PTI(T, 1)); PTI curnode; int prevdeepth = 0; //用flag标识第一次出现叶子结点,其后的所有结点应该是叶子结点 int flag = false; while (!q.empty()) { curnode = q.front(); q.pop(); if ((curnode.first->lchild == NULL && curnode.first->rchild != NULL) //只有右孩子 || curnode.first->lchild != NULL && curnode.first->rchild == NULL) //只有左孩子 return false; if (flag) { if (curnode.first->lchild == NULL && curnode.first->rchild == NULL) ; else return false; //叶子结点后续结点有非叶子结点 } else { if (curnode.first->lchild == NULL && curnode.first->rchild == NULL) { if (curnode.second > prevdeepth) { //每一层的第一个结点一定大于前一结点的层数 flag = true; } else { //如果层数不大于前一结点层数,那一定是同一层 return false; } } else { q.push(PTI(curnode.first->lchild, curnode.second + 1)); q.push(PTI(curnode.first->rchild, curnode.second + 1)); } } prevdeepth = curnode.second; } return true; } //查询 Btree Inquire_node(Btree T, char x) { if (!T) return NULL; if (x == T->data) return T; return Inquire_node(T->lchild, x) != NULL ? Inquire_node(T->lchild, x) : Inquire_node(T->rchild, x); } //递归求解所有叶子结点到根结点的路径 void Every_path_recursion(Btree T, char E_path[], int len) { if (T) { if (T->rchild == NULL && T->rchild == NULL) { cout << T->data; for (int i = len - 1; i >= 0; i--) cout << E_path[i]; cout << endl; } else { E_path[len] = T->data; len++; Every_path_recursion(T->lchild, E_path, len); Every_path_recursion(T->rchild, E_path, len); len--; } } } //非递归求所有路径(树叶到根结点) void AllPath(Btree T) { struct node { int parent; Btree node; }qu[100]; Btree q; int front, rear, p; front = rear = -1; rear++; qu[rear].node = T; qu[rear].parent = -1; while (front != rear) { front++; q = qu[front].node; if (q->lchild == NULL && q->rchild == NULL) { p = front; while (qu[p].parent != -1) { cout << qu[p].node->data << "->"; p = qu[p].parent; } cout << qu[p].node->data << endl; } if (q->lchild != NULL) { rear++; qu[rear].node = q->lchild; qu[rear].parent = front; } if (q->rchild != NULL) { rear++; qu[rear].node = q->rchild; qu[rear].parent = front; } } } //递归求解所有树根到树叶的路径 //存储所有的路径 //递归实现输出从根节点到叶子结束的所有路径 vector path1(10, '0'); void All_path_root_leaf(Btree T, int pos) { if (T == NULL) return; path1[pos] = T->data; if (T->rchild == NULL && T->lchild == NULL) { auto it = path1.begin(); auto end = find(path1.begin(), path1.end(), '0'); while (it != end) { cout << *it++ << " "; } cout << endl; } else { if (T->data != NULL) { All_path_root_leaf(T->lchild, pos + 1); } if (T->rchild != NULL) { All_path_root_leaf(T->rchild, pos + 1); } } path1[pos] = '0'; } vector path; void Find_First_Longest_Path(Btree T) { path.push_back(T->data); if (T->lchild == NULL && T->rchild == NULL) return; else if (Depth(T->lchild) >= Depth(T->rchild)) Find_First_Longest_Path(T->lchild); else Find_First_Longest_Path(T->rchild); } void Print_First_Longest_Path(Btree T) { vector ::iterator it; for (it = path.begin(); it != path.end(); it++) cout << *it << " "; path.clear(); } void One_Longest_Path(Btree T)//其中一条 { if (T != NULL)//在T不为空的情况下 { if (Depth(T->lchild) > Depth(T->rchild))//判断往左走还是往右走 { One_Longest_Path(T->lchild); cout << T->data; } else { One_Longest_Path(T->rchild); cout << T->data; } } } //求解树的所有叶子 void PrintLeaves(Btree T) { if (T) { if (!T->rchild && !T->lchild) //如果BT节点是叶子 cout << T->data << " "; PrintLeaves(T->rchild); PrintLeaves(T->lchild); } } //统计二叉树的各个结点数量 void Sum_node(Btree T, int& zero, int& one, int& two) { if (T) { if (T->rchild != NULL && T->lchild != NULL) two++; else if (T->rchild == NULL && T->lchild == NULL) zero++; else one++; Sum_node(T->rchild, zero, one, two); Sum_node(T->lchild, zero, one, two); } } //求解二叉树的所有结点个数 int getAllNode(Btree T) { if (NULL == T) return 0; return 1 + getAllNode(T->lchild) + getAllNode(T->rchild); } //交换树的左右孩子 void swap(Btree& T1, Btree& T2) { Btree t; t = T1; T1 = T2; T2 = t; } void Node_Swap(Btree& T) { if (T) { if (T->rchild != NULL && T->lchild != NULL) { swap(T->rchild, T->lchild); } else if (T->lchild != NULL && T->rchild == NULL) { T->rchild = T->lchild; T->lchild = NULL; } else if (T->lchild == NULL && T->rchild != NULL) { T->lchild = T->rchild; T->rchild = NULL; } else { ;//空操作 } Node_Swap(T->lchild); Node_Swap(T->rchild); } else { ;//空操作 } } void inOrder(Bntree T) { if (T != NULL) { if ((T->data == '*' || T->data == '/') && (T->lchild->data == '+' || T->lchild->data == '-') && (T->rchild->data == '-' || T->rchild->data == '+'))//左右两边都需要加括号 { cout << "("; inOrder(T->lchild); cout << ")"; cout << T->data; cout << "("; inOrder(T->rchild); cout << ")"; } else if ((T->data == '*' || T->data == '/') && (T->lchild->data == '+' || T->lchild->data == '-' || T->rchild->data == '-' || T->rchild->data == '+')) { inOrder(T->lchild); cout << T->data; cout << "("; inOrder(T->rchild); cout << ")"; } else { inOrder(T->lchild); cout << T->data; inOrder(T->rchild); } } } typedef struct StackNode { Btree data_tree; //存储的是二叉树 char data_op; //存储的是符号 StackNode* next; }*linkStack; //栈的初始化 int InitStack(linkStack& S) { S = NULL; return 1; } //二叉树入栈 int Push_tree(linkStack& S, Btree e) { linkStack p = new StackNode; p->data_tree = e; p->next = S; S = p; return 1; } //字符(运算符号)入栈 int Push_op(linkStack& S, char e) { linkStack p = new StackNode; p->data_op = e; p->next = S; S = p; return 1; } //二叉树出栈 int Pop_tree(linkStack& S, Btree& T1) { if (S == NULL) return 0; linkStack p = S; T1 = p->data_tree; S = S->next; delete p; return 1; } //字符(运算符号)出栈 int Pop_op(linkStack& S, char& ch) { if (S == NULL) return 0; linkStack p = S; ch = p->data_op; S = S->next; delete p; return 1; } //取栈顶元素 char GetTop_op(linkStack S) { if (S != NULL) return S->data_op; else return ' '; } Btree GetTop_tree(linkStack S) { if (S != NULL) return S->data_tree; else return NULL; } //创建以T为根结点的二叉树(存储符号) void CreateExpTree(Btree& T, Btree a, Btree b, char theta)//a是左孩子,b是右孩子,theta是数据域 { Btree L = new Tnode; L->data = theta; L->lchild = a; L->rchild = b; T = L; } //创建以T为根结点的二叉树(存储数值,可大于9) //a是左孩子,b是右孩子,theta是数据域 void CreateExpTree_str(Btree& T, Btree a, Btree b, string theta) { Btree L = new Tnode; L->combine_data = theta; L->lchild = a; L->rchild = b; T = L; } //比较运算符的优先级 //top是栈顶元素,ch是需要比较的元素 char Precede(char top, char ch) { if (ch == ')' && top == '(') return '='; else if (ch == ')') return '>'; if (top == ' ' || top == '(' || ch == '(') return '<'; if (ch == '=') return '>'; if (top == '+' || top == '-') { if (ch == '+' || ch == '-') return '>'; else if (ch == '/' || ch == '*') return '<'; } else if (top == '*' || top == '/') return '>'; } //创建表达式树 //expt栈(根结点),optr栈(运算符) void InitExpTree(char ep[], linkStack& expt, linkStack& optr) { int n = strlen(ep); int i = 0; Btree T = NULL; //树根 Btree T1 = NULL; //左子树 Btree T2 = NULL; //右子树 char ch = ' '; //弹出的符号 string combine_str = ""; //存储数值,可大于9 while (i != n) { if (ep[i] >= '0' && ep[i] <= '9') { //数值(二叉树),进入expt栈中 combine_str += ep[i]; if (ep[i + 1] >= '0' && ep[i + 1] <= '9') { //下一位仍是数字,需连接 i++; continue; } CreateExpTree_str(T, NULL, NULL, combine_str); combine_str = ""; //建完数值的二叉树后string要置空 Push_tree(expt, T); i++; } else { switch (Precede(GetTop_op(optr), ep[i])) //比较优先级 { case '<': Push_op(optr, ep[i]); i++; break; case '>': Pop_op(optr, ch); //弹出上一个字符 Pop_tree(expt, T1); //弹出上两个数值(二叉树) Pop_tree(expt, T2); CreateExpTree(T, T2, T1, ch); //以data_tree为根,连接T1和T2两颗子树 Push_tree(expt, T); //最后把T放进expt栈中 break; case '=': Pop_op(optr, ch); i++; break; default: break; } } } } //表达式树的后序遍历 void PostOrder_get(Btree T) { if (T) { PostOrder_get(T->lchild); PostOrder_get(T->rchild); if (T->lchild == NULL && T->rchild == NULL) { cout << T->combine_data << " "; } else cout << T->data << " "; } } //根据当前结点运算符的例子那个进行相应运算 double GetValue(char data, double lvalue, double rvalue) { switch (data) { case '+': return lvalue + rvalue; break; case '-': return lvalue - rvalue; break; case '*': return lvalue * rvalue; break; case '/': return lvalue / rvalue; break; default: break; } } //把string字符转换成数值 double change(string str) { int n = str.length(), m = str.length(); double sum = 0; for (int i = 0; i < n; i++) { sum += (str[i] - '0') * pow(10, m - 1); m--; } return sum; } //遍历表达式树求表达式的值 double evaluateExpTree(Btree T) { double lvalue = 0, rvalue = 0; //存放叶子结点的数据域初始为0 if (T->lchild == NULL && T->rchild == NULL) return change(T->combine_data); //return T->data - '0'; else { lvalue = evaluateExpTree(T->lchild); //相当于后序遍历二叉树 rvalue = evaluateExpTree(T->rchild); return GetValue(T->data, lvalue, rvalue); } } void Func() { Clear(); //char ep[] = "3+4*(6-1)-8/2#"; //"(18-2)*(13-7)+4/2#"; char s[maxsize]; int i = 0; cout << "请输入表达式 ..." << endl; while (cin >> s && s != "=") { if (s[0] == '0') Index(); linkStack expt; InitStack(expt); //初始化expt栈(根结点) linkStack optr; InitStack(optr); //初始化optr栈(运算符) InitExpTree(s, expt, optr); //构建表达式树 Btree T = NULL; Pop_tree(expt, T); //获取最后建好的二叉树 cout << "初始的中缀表达式: " << s << endl; //初始中缀表达式 cout << "后序遍历: "; PostOrder_get(T); //后序遍历结果 cout << endl; cout << "表达式求值后的结果: " << evaluateExpTree(T) << endl; //表达式树求值结果 i++; if (i > 0) cout << "请继续输入表达式求值或输入 0 返回主菜单..." << endl; } }



