波蘭表示法與表達式樹
來自專欄 Milo的編程
昨晚撰寫答案《Milo Yip:怎麼用 C 語言畫出二叉樹的圖形?》,以 ASCII 字元列印任意深度的滿二叉樹(full binary tree)。評論中問及如何列印非滿二叉樹。我記起,整個滿二叉樹可存儲在單個一維數組。那麼,可以先把非滿二叉樹的節點寫到一維數組,然後修改列印程序,如果數組中存有該序號的節點,才列印該節點及其指向父節點的連線,否則列印空白佔位字元。
我的回評或過於簡短,不夠清晰,因此我想用實際代碼解釋。然而,怎樣建一個非滿二叉樹?我想到可以寫一個簡單的表達式解析器,支持加減乘除,不支持負數操作數。程序也能列印出其表達式樹。
最簡單的表達式語法,莫過於波蘭表示法(Polish notation)。波蘭表示法又稱為前綴表示法,即運算符寫在前面。波蘭表示法的特點是不需要括弧。例如,表達式(1 + 2) * (3 - 4)
的波表示法是 * + 1 2 - 3 4
。
(題圖 photo by Elliott Engelmann)
首先設計解析後的數據結構,表達式樹的節點可能是運算符或操作數:
typedef enum { NUM, ADD, SUB, MUL, DIV } Type;typedef struct NodeTag { union { double number; struct NodeTag *children[2]; } u; Type type;} Node;
因為一個節點不會同時為運算符或操作數,採用 union
可能節省一點內存。
波蘭表示法的解釋器非常簡單,可通過遞歸實現,不需要額外的數據結構:
Node* parse(char** s) { while (isspace(**s)) (*s)++; if (**s ==