1. 程式人生 > >Hdu1805-Expression(表示式樹模版題+層序遍歷樹+棧的基本應用)

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 }