簡單算術表示式二叉樹的構建和求值 資料結構

2021-10-11 03:07:25 字數 3662 閱讀 4449

題目要求

先用二叉樹來表示乙個簡單算術表示式,樹的每乙個結點包括乙個運算子或運算數。在簡單算術表示式中只包含 加 減 乘 除 和一位正整數且格式正確(不包括括號),並且要按照先乘除後加減的原則構造二叉樹,下圖所示為 「1+2*3-4/5」 代數表示式對應的二叉樹,然後由對應的二叉樹計算該表示式的值。

先用二叉樹來表示乙個簡單算術表示式,樹的每乙個結點包括乙個運算子或運算數。

在簡單算術表示式中只包含 + - * / 和一位正整數且格式正確(不包括括號),

並且要按照先乘除後加減的原則構造二叉樹,下圖所示為 「1+2*3-4/5」 代數表示式對應的二叉樹,

然後由對應的二叉樹計算該表示式的值。

思考過程

按照題目所述, 自己根據乙個更複雜更全面的表示式(出現了所有的情況),畫多乙個圖,尋找規律。

表示式的要求:

(1)要出現 + - * / 中所有的符號

(2)各優先順序符號要出現不同的次數來相互搭配

如:1+2+3*4*5+6+7+8/2*9+9

我大意了,在作圖的時候忘記用減號 - 了,但在這裡沒有影響

二叉樹的特點

1. 數字只能是葉子節點, 且葉子節點只能是數字

2. + - 符號永遠只能祖宗節點或者左孩子節點

3. 如果遇到 * / 則 將其作為祖宗節點來看, 其右孩子節點只能是 數字, 左孩子節點是 * / 符號或者 數字

思路分析
1. 遍歷字串,利用棧儲存節點:

p = new btnode;

p->lchild = null;

p->rchild = null;

(1) 遇到數字:

思路:若分情況討論情況:

1. 棧為空,即這是字串第乙個數字

2. 左右邊可能為 + - * / 其中之一,

3. 而如果是乘除,則要先進行乘除運算

可見,如果對數字進行分情況處理,將會十分複雜,

不妨考慮直接將其壓棧,

在遇到運算子在進行符號的優先順序進行討論。

**操作:p->elem = ch; sta.push(p);

(2) 遇到乘除:

思路:將 * (或/) 作為父節點,

左節點為棧頂元素 num1 或者 * (或/),

右節點為字串下乙個元素num2

**操作:新建節點 p 賦值 * (或/),

新建節點 r 賦值 字串下乙個元素num2,

彈出棧頂元素作為節點l,

然後連線:p->lchild = l, p->rchild = r;

p->elem = ch;

btnode *r = new btnode;

i++;

r->elem = str[i];

r->lchild = null;

r->rchild = null;

p->rchild = r;

p->lchild = sta.top();

sta.pop();

sta.push(p);

(3) 遇到加減:

思路:通過觀察二叉樹中,父節點的左右孩子節點的各種可能找出規律

兩種情況: [1]棧內元素個數為2,

則棧頂元素必為 * 或 / ,

則將其作為當前節點右的孩子節點,

然後弾棧,剩下元素處理過程與 [2] 一致

[2]棧內元素個數為1,

則棧內元素必為 +、-、數字(首數字)其中之一,

則將其作為當前節點的左孩子節點即可,

然後弾棧,將當前節點壓棧

**操作:

p->elem = ch;

if(sta.size() == 2)

p->lchild = sta.top();

sta.pop();

sta.push(p);

2. 遍歷字串完成後,觀察到有幾種情況

(1)只有 + (或-)操作, 則棧內有兩個元素,

棧底元素是數字,棧頂元素是運算子。

(2)只有 * 或(/)操作,則棧內只有乙個運算子。

(3)既有 + (或-)操作也有 * 或(/)操作,則棧內有兩個元素,

棧底元素是 * (或/)或數字,棧頂元素是運算子。

所以可以看成(2)是一種情況,(1)(3)是另一種情況

**操作:

if (sta.size() == 2)

bt = sta.top();

**實現
#include

#include

#include

#include

using

namespace std;

#define elemtype char

typedef

struct node btnode;

void

createbt

(btnode*

&bt, string str)

else

if(ch ==

'+'|| ch ==

'-')

p->lchild = sta.

top();

sta.

pop();

sta.

push

(p);

}else

p =null

;free

(p);}if

(sta.

size()

==2) bt = sta.

top();

}int

calculate

(btnode*

&bt)

void

displaybt

(btnode*

&bt)

else

}void

destroybt

(btnode*

&root)

}int

main()

運算結果

總結

知識點:根據算術運算子的優先順序進行分類討論,運用了棧這一資料結構。

拓展思考:上述**先把 * (或/) 的運算進行操作,

而 + (或-) 則先存在棧裡,不難發現,

可以不通過構建二叉樹,利用棧來運算簡單的表示式。

拓展知識:

題目所給這一類表示式叫中綴表示式,

指操作符是以中綴形式處於運算元的中間,

這一類表示式是人們常用的算術表示方法,

但通過這道題可以發現,中綴表示式不容易被計算機解析,

要使用還要經過處理(利用棧)。

而字首表示式(波蘭式,波蘭數學家jan lukasiewicz)

與字尾表示式(逆波蘭式, rpn),則更容易被計算機進行識別運算。

(資料結構)簡單算術表示式二叉樹的構建和求值

編寫乙個程式,先用二叉樹來表示乙個簡單算術表示式,樹的每乙個結點包括乙個運算子或運算數。在簡單算術表示式中只包含 和一位正整數且格式正確 不包括括號 並且要按照先乘除後加減的原則構造二叉樹,圖7.34所示為1 2 3 4 5代數表示式對應的二叉樹,然後由對應的二叉樹計算該表示式的值。如上圖所示的二叉...

先綴表示式構建表示式二叉樹

在表示式二叉樹的學習中,有很多有趣的構造其表示式二叉樹的方法,其中先綴表示式構建表示式二叉樹常見有很多都是利用遞迴的方式去構建,但在閱覽的一篇文件中,引出了非遞迴方式構建其表示式二叉樹概念,雖然相對更麻煩,但在其 實現,探索上還是很有意義的.c語言實現 先綴表示式 23 45 如圖,如果從左到右讀取...

根據中綴表示式構建二叉樹

本文從中綴表示式轉字尾表示式開始,循序漸進介紹根據中綴表示式構建二叉樹的過程。從左往右遍歷中綴表示式,無視空格 遇到運算元直接輸出 遇到操作符通過按照以下規則處理 在遍歷完中綴表示式時讓操作符棧的最後元素出棧 例子 將 2 5 3 1轉換為字尾表示式 基於上面中綴表示式轉字尾表示式的步驟,新增乙個運...