(方法)二叉樹的廣義表形式,建樹和輸出
二叉樹的廣義表示形式:
a:表示根節點為a,左右節點均為空
a(b):表示根節點為a,左節點為b,右節點為空
a(,c):表示根節點為a,左節點為空,右節點為c
a(b,c)表示父節點為a,左子節點與右子節點分別為b和c
同樣的表示方法還有a(b(d),c)
儲存廣義表二叉樹的方法:
將廣義表建立成二叉樹,可以藉助棧來實現。
利用棧先進先出的特點,如果左孩子節點不為空,則將其作為棧頂節點(即父親節點)的左孩子並壓入棧中,遞迴左子樹
如果右孩子不為空,則將其作為棧頂元素的右孩子並壓入棧中,遞迴右子樹
虛擬碼如下:
設定一個標記變數 k,初始為 -1; 設定一個標記節點 p; 迴圈遍歷儲存廣義表的字串 str: 如果 str[i] 是左括號: 則設定 k 為 0; 把 p 壓入棧中。 否則如果 str[i] 是逗號: 則設定 k 為 1。 否則如果 str[i] 是右括號: 則棧頂元素出棧。 否則如果 str[i] 是一個字母,用節點 temp 來儲存: 如果 k 為 -1: 則把 temp 作為根節點並壓入棧中。 如果 k 為 0: 如果此時棧頂節點是 p,則先出棧; 然後將 temp 作為棧頂節點的左孩子; 再把 temp 壓入棧中。 如果 k 為 1: 棧頂元素出棧; 將 temp 作為棧頂節點的右孩子; 再把 temp 壓入棧中。
程式碼實現:
Node* build(const string& input) { stack<Node*> treeStack; int k = -1; for (int i = 0; i < input.length(); ++i) { if (input[i] == '(') { k = 0; treeStack.push(new Node(input[i])); } else if (input[i] == ',') { k = 1; } else if (input[i] == ')') { treeStack.pop(); } else { Node* temp = new Node(input[i]); //暫存 if (k == -1) { treeStack.push(temp); } else if (k == 0) { treeStack.pop(); //棧頂元素出棧 treeStack.top()->lchild = temp; treeStack.push(temp); } else if (k == 1) { treeStack.pop(); treeStack.top()->rchild = temp; treeStack.push(temp); } } } return treeStack.top(); //最後返回的是根節點 }
儲存廣義表二叉樹的方法:
輸出二叉樹的廣義表形式,有點類似於二叉樹的先序遍歷
先輸出根節點,如果左孩子不為空則遞迴輸出左子樹,如果右孩子不為空則遞迴輸出右子樹,在輸出過程中,根據節點是否為空,在合適的地方輸出左右括號及逗號
虛擬碼如下:
輸出節點儲存的值; 如果左孩子不為空: 輸出 "("; 遞迴輸出左子樹; 如果右孩子為空: 輸出 ")"。 如果右孩子不為空: 如果左孩子為空: 輸出 "("。 輸出 “,”; 遞迴輸出右子樹; 輸出 ")"。
程式碼如下:
void print() { cout << data; if (lchild != nullptr) { cout << "("; lchild->print(); if (rchild == nullptr) { cout << ")"; } } if (rchild != nullptr) { if (lchild == nullptr) { cout << "("; } cout << ","; rchild->print(); cout << ")"; } }