程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> [代碼實例]運用表達式樹將後綴表達式轉換成中綴表達式,表達式中綴

[代碼實例]運用表達式樹將後綴表達式轉換成中綴表達式,表達式中綴

編輯:C++入門知識

[代碼實例]運用表達式樹將後綴表達式轉換成中綴表達式,表達式中綴


  在前面的文章中,使用了棧這一數據結構將通常使用的中綴表達式轉換成了後綴表達式,並再一次使用棧來對後綴表達式求值,從而計算出了表達式的值.

  現在使用樹這一數據結構來將後綴表達式還原為中綴表達式.使用的是表達式樹.表達式樹是二叉樹的一種,所謂二叉樹,要麼它為為空樹,要麼不為空樹,並且每個節點最多有兩個孩子.而表達式樹則是二叉樹的一種,它的葉節點全為表達式中的數字,其余節點是運算符,即加,減,乘,除的運算符號.如圖所示,就是一棵表達式樹:

 

  它的特點顯而易見.若我們對其進行先序遍歷(preorder),將獲得該表達式的前綴版本(前綴表達式):-+3*29/64;對其中序遍歷(inorder),得到中綴表達式:3+2*9-6/4;對其後序遍歷(postorder),得到後綴表達式:329*+64/-.

  通過給出某個版本的表達式,可以構建一棵該表達式所對應的表達式樹.以後綴表達式為例,樹節點的結構如下:

1 struct  EtreeNode
2 {
3     char value;            //節點的值
4     EtreeNode *left;     //指向左孩子   
5     EtreeNode *right;  //指向右孩子
6 };    

  構造一棵表達式樹,需要用到棧.算法與後綴表達式求值的算法很相似.若輸入是一個數字,創建一個節點指針,保存該數字,左右孩子指針皆為空(nullptr),將該節點指針壓棧;若輸入是運算符號,同樣的申請空間建立節點指針保存它,再從棧中彈出兩個節點指針作為該指針的左右孩子域.依次進行,直到輸入完結,彈棧,得到的是對應的表達式樹的根節點.

  C++實現如下:

 1 EtreeNode* creat_etree(const string &in)           //構建表達式樹
 2 {
 3     if (!isdigit(in.at(0)))                                            //第一個輸入若為運算符
 4     {
 5         try
 6         {
 7             ;
 8             throw runtime_error("illegal expression");
 9         }
10 
11         catch (runtime_error err)
12         {
13             cout << err.what() << endl;
14             exit(EXIT_FAILURE);
15         }                                                                        //第一個輸入若為運算符,拋出異常,程序結束運行
16     }
17 
18     stack <EtreeNode*> ptrStack;                                //保存節點指針的棧
19 
20     for (auto &i : in)                                                    //遍歷整個輸入字符串
21     {
22         if (isdigit(i))                                                        //若為數字
23         {
24             EtreeNode *ptr = new EtreeNode;
25             ptr ->value = i;
26             ptr ->left = ptr ->right = nullptr;
27             ptrStack.push(ptr);                                        //保存該數字並壓棧
28         }
29 
30         else                                                                    //為運算符
31         {
32             EtreeNode *b = ptrStack.top();
33             ptrStack.pop();
34 
35             EtreeNode *a = ptrStack.top();
36             ptrStack.pop();                                                //彈出兩個數字
37 
38             EtreeNode *ptr = new EtreeNode;
39 
40             ptr ->value = i;
41             ptr ->left = a;
42             ptr ->right = b;
43             ptrStack.push(ptr);                                        //指針指向兩個數字並壓棧
44         }
45     }
46 
47     EtreeNode *root = ptrStack.top();                            //彈出根節點
48     ptrStack.pop();
49 
50     return root;
51 }

  這樣,表達式樹構建完成,其根節點指針為root,通過其即可訪問整課表達式樹.需要什麼版本的表達式,就對其進行相應的遍歷.如進行中序遍歷得到中綴表達式:

 1 void inorder_traversal(EtreeNode *r)        //遞歸進行中序遍歷
 2 {
 3     if (r == nullptr)
 4         return;
 5 
 6     else
 7     {
 8         inorder_traversal(r ->left);                //引用左子樹
 9         cout << r ->value;                        //引用根節點
10         inorder_traversal(r ->right);            //引用右子樹
11     }
12 }

  這也是一種將後綴表達式轉換為中綴表達式的方法.

謝謝大家!轉載請注明出處,謝謝合作!

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved