表达式二叉树·实验代码

  • 格式:doc
  • 大小:69.50 KB
  • 文档页数:6

实验:表达式二叉树实验要求:建立表达式二叉树,并打印(可逆时针旋转90度打印,也可尝试正向打印)以中缀表达式a*b+(c-d)/e-f 为例,建立以"-"号为根的表达式二叉树。

提示:若直接利用中缀表达式建立困难,可先将中缀表达式转化为后缀表达式(可利用栈中的中缀到后缀转化程序实现中缀表达式到后缀表达式的转换,再根据后缀表达式建立表达式二叉树,可参考栈中后缀表达式计算方法)。

实验代码:#include <iostream>#include <stack>#include <string>#include <queue>#include <vector>using namespace std;class tnode;void buildexptree(const string &exp);void printexptree();int judgerank(char ch);bool isoperator(char ch);void test();void setxy(tnode *tn, int y);int X = 0;int Y = 0;int depth = 0;vector<tnode*>vt;class tnode{public:char nodeValue;int x, y;tnode *left;tnode *right;tnode(){x = 0;y = 0;}tnode(char &item, tnode *lptr = NULL, tnode *rptr = NULL):nodeV alue(item), left(lptr), right(rptr){x = 0;y = 0;}};tnode *myNode;bool cmp(tnode *t1, tnode *t2){if(t1->y != t2->y)return (t1->y) > (t2->y);return (t1->x) < (t2->x);}class zpair{ //将operator和rank打包为一体,临时存储在stk2中public:char op;int rank;zpair(){}zpair(char _op, int _rank){op = _op;rank = _rank;}};int judgerank(char ch){if(ch == '(') return -1;if(ch == '+' || ch == '-') return 1;if(ch == '*' || ch == '/') return 2;return 0;}bool isoperator(char ch){if(ch == '(' || ch == ')' || ch == '+' || ch == '-' || ch == '*' || ch == '/') return true;elsereturn false;}void buildexptree(const string &exp){stack<tnode*>stk1;stack<zpair>stk2;int i;int len = exp.length();char ch;zpair tz;zpair ztop;for(i=0; i<len; i++){ch = exp[i];if(!isoperator(ch)){ //exp[i] is an operand, so create a tnode using exp[i] and push to stk1tnode *ptr1 = new tnode(ch);stk1.push(ptr1);}else {tz.op = ch;tz.rank = judgerank(ch);if(stk2.empty())stk2.push(tz);else if(ch == '(')stk2.push(tz);else if(ch == ')'){ztop = stk2.top();while(ztop.op != '('){tnode *ptr2 = stk1.top();stk1.pop();tnode *ptr3 = stk1.top();stk1.pop();tnode *ptr4 = new tnode(ztop.op, ptr3, ptr2);stk1.push(ptr4);stk2.pop();ztop = stk2.top();}stk2.pop();}else{ztop = stk2.top();while(tz.rank <= ztop.rank){tnode *ptr5 = stk1.top();stk1.pop();tnode *ptr6 = stk1.top();stk1.pop();tnode *ptr7 = new tnode(ztop.op, ptr6, ptr5);stk1.push(ptr7);stk2.pop();if(stk2.empty()) break;else ztop = stk2.top();}stk2.push(tz);}}}while(!stk2.empty()){tnode *ptr8 = stk1.top();stk1.pop();tnode *ptr9 = stk1.top();stk1.pop();tnode *ptr10 = new tnode(stk2.top().op, ptr9, ptr8);stk1.push(ptr10);stk2.pop();}myNode = stk1.top();}int main(){freopen("chris.txt","r",stdin);string exp;cout << "Please input an expression:" << endl;cin >> exp;buildexptree(exp);cout << "The expression tree is: " << endl;printexptree();return 0;}void test(){ //测试函数cout << "testing..." << endl;}void printexptree(){setxy(myNode, Y);sort(vt.begin(),vt.end(),cmp);int tmpY = 1;int tmpX = 0;for(int i=0; i<vt.size(); i++){if(vt[i]->y < tmpY){cout << endl;tmpX = 0;tmpY--;}cout << string(vt[i]->x - tmpX - 1 , ' ') << vt[i]->nodeValue;tmpX = vt[i]->x;}cout << endl;}void setxy(tnode *tn, int y){ //设定每一个节点的横坐标if(tn == NULL) return;setxy(tn->left, y-1);tn->x = ++X;tn->y = y;vt.push_back(tn);/* cout << "tn->nodeValue=" << tn->nodeValue << " " << "tn->x=" << tn->x << " " << "tn->y=" << tn->y << endl;*/setxy(tn->right,y-1);depth++;}实验截图:实验分析:通过类tnode构造了一个表达式二叉树,除了节点值nodeValue,左分支left 和右分支right,还引入了x,y作为标定的坐标,打印时使用。

首先完成infix2postfix,这其中使用了stk1,stk2两个栈分别存储子树和zpair量,zpair是将operator与其优先级打包的一个整体,然后通过比较优先级,调整stk1中的元素,构造了后缀表达式。

打印过程中,先调用setxy()方法来设定每个节点的坐标值,使用的是中序遍历,同时声明了存储各个节点的向量vt,将所有节点压入vt后先按y再按x排序,然后按格式输出表达式二叉树。