編寫乙個程式,先用二叉樹來表示乙個簡單算術表示式,樹的每乙個結點包括乙個運算子或運算數。在簡單算術表示式中只包含+、-、*、/
和一位正整數且格式正確**(不包括括號)**,並且要按照先乘除後加減的原則構造二叉樹,圖7.34所示為1+2*3-4/5
代數表示式對應的二叉樹,然後由對應的二叉樹計算該表示式的值。
如上圖所示的二叉樹,就表示表示式1+2*3-4/5
,如果我們需要計算他,就需要採用前序遍歷的方法。
如下圖所示是隨便構造的一顆二叉樹
他表示的是表示式:5 + 2 - 1 * 2 / 5 + 3 + 2* 3
從圖中可以發現:
所有的葉子節點都必須是數字。
所有的非葉子節點都是符號,而且都必須有左子樹和右子樹。
不可能會存在乙個節點僅存在左子樹而不存在右子樹,或者僅存在右子樹而不存在左子樹的情況。
+
-
節點只存在於最左邊,左孩子只能是+
-
或者數字,右孩子只能是*
/
或者數字
*
/
節點的右孩子只能是數字,左孩子只能是*
/
或者數字
第1 2 3條非常好理解,主要是第4條和第5條
第4條:因為我們計算的時候是採用前序遍歷,前序遍歷的順序是自身、左子樹、右子樹,那麼遞迴返回的順序是右子樹、左子樹,乘法和除法的優先順序高,所以必須要先算完乘除再算加減,所以加減號要放在左邊
第5條:舉個反例:
這個樹表示1 / (2 * 5)
,而我們的表示式是不帶括號的。
建樹方法:從右往左掃瞄字串,優先尋找+
-
,如果不存在+
-
則尋找*
/
,如果都不存在,說明這是乙個葉子節點。一旦尋找到了符號,都會利用該符號之前的子串來遞迴構建左子樹,右邊的子串會用來遞迴構建右子樹。
#include
using
namespace std;
struct treenode
treenode
(char v,treenode* l,treenode *r)};
/*string字串轉換成int型別
*/int
stringtoint
(string s)
return res;}/*
構造二叉樹
*/treenode*
init
(string s)
//首先找到+或者-
int i = s.
size()
-1;while
(i>=
0&& s[i]
!='+'
&& s[i]
!='-')if
(i >=0)
//找不到+-就找乘除
i = s.
size()
-1;while
(i>=
0&& s[i]
!='*'
&& s[i]
!='/')if
(i >=0)
//找不到,則說明這是乙個數值
treenode* t =
newtreenode
(stringtoint
(s))
;return t;}/*
計算*/
double
calcular
(treenode* t)
double res =0;
if(t-
>left && t-
>right)
}else
return res;}/*
遞迴銷毀二叉樹
*/void
destory
(treenode* node)
destory
(node-
>left)
;destory
(node-
>right)
; node-
>left =
null
;//銷毀之後需要把指標置空
node-
>right =
null
;delete node;
}int
main()
如果存在什麼不對的地方,歡迎指正!
簡單算術表示式二叉樹的構建和求值 資料結構
題目要求 先用二叉樹來表示乙個簡單算術表示式,樹的每乙個結點包括乙個運算子或運算數。在簡單算術表示式中只包含 加 減 乘 除 和一位正整數且格式正確 不包括括號 並且要按照先乘除後加減的原則構造二叉樹,下圖所示為 1 2 3 4 5 代數表示式對應的二叉樹,然後由對應的二叉樹計算該表示式的值。先用二...
二叉樹的簡單應用 表示式樹
算數表示式是分層的遞迴結構,乙個運算子作用於相應的運算物件,其運算物件又可以是任意複雜的表示式。二叉樹的遞迴結構正好用來表示這種表示式。下面只討論二元表示式。二元表示式可以很自然的聯絡到二叉樹 以基本運算物件作為葉節點中的資料 以運算子作為非葉節點中的資料,其兩棵子樹是它的運算物件,子樹可以是基本運...
輸出以二叉樹表示的算術表示式
編寫程式,輸出以二叉樹表示的算術表示式,若該表示式中含有括號,則在輸出時應添上。按先序輸入一行字元,其中 表示取消建立子樹結點,即所有葉子節點均為 輸出該二叉樹所表示的算術表示式 若表示式中含有括號,則在輸出時應添上 include includetypedef struct binarytree ...