Hdu1805-Expression(表示式樹模版題+層序遍歷樹+棧的基本應用)
阿新 • • 發佈:2018-12-30
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; 32for(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 }