一般的算數式也可以轉換成二元運算樹 (Binary Expression Tree) 的方式, 建立的方法可以根據以下兩種規則 :
現在考慮運算式 : A-B*(-C+-3) :
接著便可以藉由二元運算樹進行前序與後序走訪得到此運算式的前序法與後序法.
範例代碼 :
這裡以鏈結串列來實現二元運算樹, 詳細代碼如下 :
* OperBTreeInLS.h 代碼 :
- #include
- using namespace std;
- class OperBTreeNode{
- public:
- int data;
- class OperBTreeNode *left;
- class OperBTreeNode *right;
- OperBTreeNode(){
- data = -1;
- left = NULL;
- right = NULL;
- }
- };
- typedef class OperBTreeNode obtNode;
- typedef obtNode *obtNodePoint;
- class OperBTreeInLS{
- obtNodePoint root;
- public:
- OperBTreeInLS(){
- root = NULL;
- }
- virtual void inOrder(); /*中序走法*/
- virtual int answer(); /*計算運算式二元樹的結果*/
- virtual void add_Node_To_Tree(int value);
- virtual obtNodePoint create(char seq[100], int index, int arraySize);
- virtual void cleanAll(); /*清除二元樹設定*/
- protected:
- virtual void _cleanAll(obtNodePoint ptr);
- virtual void _inOrder(obtNodePoint ptr);
- /*判斷運算式如何運算的方法宣告*/
- virtual int _condition(char opr, int num1, int num2);
- virtual int _answer(obtNodePoint ptr);
- };
- #include "OperBTreeInLS.h"
- int OperBTreeInLS::answer(){
- return _answer(root);
- }
- int OperBTreeInLS::_answer(obtNodePoint ptr){
- if(ptr != NULL) {
- int firstNumber = 0;
- int secondNumber = 0;
- if(ptr->left == NULL && ptr->right ==NULL) {
- return ptr->data - 48; //ASCII char '0' = 48
- } else {
- firstNumber = _answer(ptr->left);
- secondNumber = _answer(ptr->right);
- return _condition((char)ptr->data, firstNumber, secondNumber);
- }
- }
- return -1;
- }
- void OperBTreeInLS::add_Node_To_Tree(int value) {
- /*Not implement here*/
- }
- obtNodePoint OperBTreeInLS::create(char seq[], int index, int arraySize) {
- obtNodePoint tmpPoint;
- if(seq[index]=='0' || index >= arraySize) {
- return NULL;
- } else {
- tmpPoint = new obtNode;
- if(root == NULL)
- root = tmpPoint;
- tmpPoint->data = seq[index];
- tmpPoint->left = NULL;
- tmpPoint->right = NULL;
- // 建立左子樹
- tmpPoint->left = create(seq, index*2, arraySize);
- // 建立右子樹
- tmpPoint->right = create(seq, index*2+1, arraySize);
- return tmpPoint;
- }
- }
- int OperBTreeInLS::_condition(char opr, int num1, int num2) {
- switch(opr) {
- case '*': return (num1 * num2);
- case '/': return (num1 / num2);
- case '+': return (num1 + num2);
- case '-': return (num1 - num2);
- case '%': return (num1 % num2);
- }
- return -1;
- }
- void OperBTreeInLS::inOrder() {
- this->_inOrder(this->root);
- }
- void OperBTreeInLS::_inOrder(obtNodePoint ptr) {
- if(ptr != NULL) {
- this->_inOrder(ptr->left);
- cout << "[" << (char)ptr->data << "] ";
- this->_inOrder(ptr->right);
- }
- }
- void OperBTreeInLS::cleanAll() {
- cout << "Clean " ;
- this->_cleanAll(this->root);
- cout << endl;
- this->root = NULL;
- }
- void OperBTreeInLS::_cleanAll(obtNodePoint ptr){
- if(ptr!=NULL) {
- /*後序走法*/
- _cleanAll(ptr->left);
- _cleanAll(ptr->right);
- cout << (char)ptr->data << " " ;
- delete ptr;
- }
- }
- void ch06_04(bool b) {
- if(b) {
- // 第一筆運算式
- char information1[] = {' ', '+', '*', '%', '6', '3', '9', '5'};
- char information2[] = {' ', '+', '+', '+', '*', '%', '/', '*', '1', '2', '3', '2', '6', '3', '2', '2'};
- OperBTreeInLS operBTree;
- operBTree.create(information1, 1, 8);
- cout << "===二元運算樹範例(一)===" << endl;
- cout << "轉成中序運算式: ";
- operBTree.inOrder();
- cout << endl;
- cout << "此二元運算樹結果為:" << operBTree.answer() << endl;
- operBTree.cleanAll();
- operBTree.create(information2, 1, 16);
- cout << "===二元運算樹範例(二)===" << endl;
- cout << "轉成中序運算式: ";
- operBTree.inOrder();
- cout << endl;
- cout << "此二元運算樹結果為:" << operBTree.answer() << endl;
- operBTree.cleanAll();
- }
- }
執行結果 :
補充說明 :
* [ 資料結構 小學堂 ] 樹狀結構導論 : 二元樹的走訪
* Wiki - ASCII
沒有留言:
張貼留言