Hdu1805-Expression(表达式树模版题+层序遍历树+栈的基本应用)
2018-11-23-02:27:37
原题链接
题目描述:
题目一目了然。
本题思路:
本题很容易能想到是构建表达式树然后按照层序逆序输出即可。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <stack> 4 #include <queue> 5 #include <iostream> 6 using namespace std; 7 8 typedef char TElemType; 9 typedef struct BiNode { 10 TElemType Elem; 11 struct BiNode *Left_Child; 12 struct BiNode *Right_Child; 13 } BiNode, *BiTree; 14 bool IsOperator(char Elem); 15 void PrintBiTree(BiTree T); 16 BiTree ConstructingExpressionTree(string Expression); 17 18 int main() { 19 BiTree T; 20 string Expression; 21 cin >> Expression; 22 T=ConstructingExpressionTree(Expression); 23 PrintBiTree(T); 24 return 0; 25 } 26 bool IsOperator(char Elem) { 27 return (Elem == '+' || Elem == '-' || Elem == '*' || Elem == '/'); 28 } 29 30 BiTree ConstructingExpressionTree(string Expression) { 31 stack<BiTree>Operand; 32 for(int i = 0; i < Expression.length(); i++) { 33 BiTree Child; 34 if(!IsOperator(Expression[i])) { 35 Child = new BiNode; 36 Child->Elem = Expression[i]; 37 Child->Right_Child = NULL;//Operand一定是叶结点 38 Child->Left_Child = NULL; 39 Operand.push(Child); 40 } 41 if(IsOperator(Expression[i])) { 42 Child = new BiNode; 43 Child->Elem = Expression[i]; 44 Child->Right_Child = Operand.top(); 45 Operand.pop(); 46 Child->Left_Child = Operand.top(); 47 Operand.pop(); 48 Operand.push(Child);//将构造好的子表达式树的结点压入栈,便于最后汇入总表达式树 49 } 50 } 51 return Operand.top(); 52 } 53 54 void PrintBiTree(BiTree T){ 55 //按照层序遍历输出二叉树 56 if(T==NULL) return; 57 queue<BiTree>QueueTreeNode; 58 QueueTreeNode.push(T);//首先将二叉树的头结点放入队列 59 while(!QueueTreeNode.empty()){//如果队列为空则结束遍历 60 BiTree QueueNode=QueueTreeNode.front();//每次访问队列的第一个元素并将其弹出 61 QueueTreeNode.pop(); 62 cout<<QueueNode->Elem<<' '; 63 if(QueueNode->Left_Child)//将第一个元素的左右子树的结点都放入队列 64 QueueTreeNode.push(QueueNode->Left_Child); 65 if(QueueNode->Right_Child) 66 QueueTreeNode.push(QueueNode->Right_Child); 67 } 68 }
本题应熟记知识点:表达式树的构建与层序遍历二叉树。
1.构建表达式树
① 算法描述:
遍历后缀表达式,如果符号是Operand,那么我们就建立一个单结点树并将一个指向他的指针推入栈中,如果符号是Operator,那么我们就从栈中弹出指向两棵树T1和T2的那两个指针(T1的先弹出)并形成一颗新
的树,该树的根就是Operator,他的左右儿子分别指向T2和T1,然后将指向这颗新树的指针压入栈中。
② 代码:
1 BiTree ConstructingExpressionTree(string Expression) { 2 stack<BiTree>Operand; 3 for(int i = 0; i < Expression.length(); i++) { 4 BiTree Child; 5 if(!IsOperator(Expression[i])) { 6 Child = new BiNode; 7 Child->Elem = Expression[i]; 8 Child->Right_Child = NULL;//Operand一定是叶结点 9 Child->Left_Child = NULL; 10 Operand.push(Child); 11 } 12 if(IsOperator(Expression[i])) { 13 Child = new BiNode; 14 Child->Elem = Expression[i]; 15 Child->Right_Child = Operand.top(); 16 Operand.pop(); 17 Child->Left_Child = Operand.top(); 18 Operand.pop(); 19 Operand.push(Child);//将构造好的子表达式树的结点压入栈,便于最后汇入总表达式树 20 } 21 } 22 return Operand.top(); 23 } 24 25 bool IsOperator(char Elem) { 26 return (Elem == '+' || Elem == '-' || Elem == '*' || Elem == '/'); 27 }
2.二叉树的层序遍历
① 算法思路:
代码里都有。
② 代码:
1 void PrintBiTree(BiTree T) { 2 //按照层序遍历输出二叉树 3 if(T == NULL) return; 4 queue<BiTree>QueueTreeNode; 5 QueueTreeNode.push(T);//首先将二叉树的头结点放入队列 6 while(!QueueTreeNode.empty()) { //如果队列为空则结束遍历 7 BiTree QueueNode = QueueTreeNode.front(); //每次访问队列的第一个元素并将其弹出 8 QueueTreeNode.pop(); 9 cout << QueueNode->Elem << ' '; 10 if(QueueNode->Left_Child)//将第一个元素的左右子树的结点都放入队列 11 QueueTreeNode.push(QueueNode->Left_Child); 12 if(QueueNode->Right_Child) 13 QueueTreeNode.push(QueueNode->Right_Child); 14 } 15 }
时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
没有谁生来就是神牛,而千里之行,始于足下!