表示式,轉換和計算,用
c語言描述--part3
(關於表示式的所有你應該知道的東西)
其餘轉換
所有剩餘的轉換都可以輕易地用二分表示式樹來完成。事實上,上面的兩種轉換,也即中綴
->
字首和中綴
>字尾,也能用二分樹來做,但是技巧性太強,而用棧來完成就容易得多。現在我們繼續講解,首先對二分表示式樹下一定義。
二分表示式樹
表示式樹是嚴格的二分樹,葉節點存放運算元,非葉節點存放運算子,根節點存放用於計算左子樹和右子樹計算結果的運算子。一旦我們得到了某一特定表示式的樹,將它轉換成各種不同的表示形式(中綴,字首和字尾)以及計算其值都只需要遍歷這棵樹就可以了。下圖展示了前面的表示式
2*3/(2-1)+5*(4-1)
對應的表示式樹。
注意:二分表示式樹不包含括號,原因在於用樹結構計算表示式值的時候,表示式樹本身的結構就已經決定了計算的順序。
當我們先序遍歷(先訪問根節點,再依次訪問左兒子和右兒子)表示式樹時,得到的是此表示式的字首表示,類似地,後序遍歷(先依次訪問左兒子,右兒子,再訪問根節點)將得到字尾表示。如果中序遍歷(依次訪問左兒子,右兒子,根節點)表示式樹我們會得到什麼結果呢?對於不包含括號的表示式,中序遍歷將得到它的確定的中綴形式,但對那些用括號來改變運算子間優先次序的表示式,簡單的中序遍歷就不能將其還原成原來的中綴形式。
用表示式樹完成各種表示形式間的轉換
字首->中綴
後面的演算法適用於其中綴形式中沒有用括號來改變運算子間原有優先次序的表示式。
1)根據字首表示式建立一棵表示式樹
2)中序遍歷這棵樹
字首 ->字尾
1)根據字首表示式建立一棵表示式樹
2)後序遍歷這棵樹
你看這是多麼容易啊!關鍵之處在於根據字首表示式建立表示式樹,下面的演算法完成了這項工作:
根據字首表示式建立表示式樹的演算法
1)求字首表示式的逆序
2)檢查輸入的下一元素
3)假如是運算元,則
i)建立乙個葉節點,也就是沒有兒子的節點(
node- >left_child=node->right_child=null
)ii)
將運算元賦給葉節點的
data
分量iii)
葉節點位址入棧
4)假如是運算子,則
i)建立乙個節點
ii)運算子賦給該節點的
data
分量iii)
棧頂節點位址出棧,並將其賦值給新節點的
left
分量,即
node->left_child
iv)棧頂節點位址出棧,並將其賦值給新節點的
right
分量,即
node->right_child
v)新節點位址入棧
5)假如輸入還未結束,跳轉到步驟26
)假如輸入結束,棧中節點位址出棧,此位址即為整個樹的根節點位址
字首表示轉換成中綴和字尾表示的演算法參考程式#2。
字尾->中綴
同前,這裡的演算法也是只適用於其中綴形式中沒有用括號來改變運算子間原有優先次序的表示式。
1)由字尾表示式建立表示式樹
2)中序遍歷該樹
字尾->字首
1)由字尾表示式建立表示式樹
2)先序遍歷該樹
根據字尾表示式建立表示式樹的演算法
1) 檢查輸入的下一元素
2)假如是運算元,則
i)建立乙個葉節點,也就是沒有兒子的節點(
node- >left_child=node->right_child=null
)ii)
將運算元賦給葉節點的
data
分量iii)
葉節點位址入棧
3) 假如是運算子,則
i)建立乙個節點
ii)運算子賦給該節點的
data
分量iii)
棧頂節點位址出棧,並將其賦給新節點的
right
分量,即
node->right_child
iv)棧頂節點位址出棧,並將其賦給新節點的
left
分量,即
node->left_child
v)新節點位址入棧
4) 假如輸入還未結束,跳轉到步驟
25)
假如輸入結束,棧中節點位址出棧,此位址即為整個樹的根節點位址
上述演算法參考程式#2。
好了,最終我們可以完稱表示式的任意兩表示形式的轉換了。這裡我們對前面的內容作一小節:
1)中綴-
>
字首,用棧
2)中綴-
>
字尾,用棧
3) 字首-
>
中綴,用表示式樹
4) 字首-
>
字尾,用表示式樹
5) 字尾-
>
中綴,用表示式樹
6) 字尾-
>
字首,用表示式樹
現在我們所剩下的問題就是如何計算表示式的值了。計算乙個表示式的包含兩個步驟:
1)建立給定表示式所對應的二分樹
2)遞迴地計算這棵樹的值
(按照文中方法,對乙個普通的中綴表示式我們要經過中綴-
>
字首或字尾
->
表示式樹-
>
遞迴算值的過程。其實也可以用棧直接由中綴形式計算表示式的值――譯者注)
下面的函式將用遞迴的方法計算乙個表示式樹的值:
int evaluatetree (struct node* root)
if root != null
if current node contains an operator
x = evaluatetree(root -> left_child)
y = evaluatetree(root -> right_child)
perform operation on x and y, specified by the
operator and store result in z
return z
else return root->datarefer program #2 for evaluation of an expression tree.
參考程式
#2計算表示式樹的值的演算法。
C 用棧計算表示式
基本思路 1 設定兩個棧,乙個運算子棧,乙個運算元棧。初始化後將 壓入操作符棧中。2 順序掃瞄 當輸入為運算元時就將其壓入運算元棧。當輸入為運算子時,則比較輸入運算子和運算子棧的棧頂運算子的優先順序的大小。若輸入運算子的優先順序高於運算子棧頂運算子的優先順序時,則將其壓入到運算子棧 若運算子棧頂運算...
C語言 將中綴表示式轉換為字尾表示式並計算結果
本 有嚴重bug 本 有嚴重bug 本 有嚴重bug 重要的事情說三遍!請移步到 c語言課設 中綴表示式轉字尾表示式並求值 續 include include include include define elemtype int using namespace std typedef struct...
c語言用棧實現計算中綴表示式
解決這個問題需要兩步 將中綴式換成字尾式 字尾式更利於寫演算法 計算字尾式。因為還要滿足多位數和小數,所以用了字串。typedef struct x typedef struct sqstack 關於棧的一些函式就不寫了,應該都知道。下面直接給中綴式換字尾式 有注釋 void change sqst...