二叉樹的重構——需要至少有中序遍歷序列,以及前序后序任意一個
基本思路:以下以L表示左子樹/左孩子,V表示當前節點,R表示右子樹/右孩子,這里以中序+后序為例
中序遍歷序列順序為LVR,后序遍歷序列順序為LRV,因此可以直接從后序遍歷序列中找出根節點V,即序列中的最后一個元素
然后以V為分界,對中序遍歷序列進行分割——可以很容易地看出,V左側即為左子樹的中序遍歷序列,右側即為右子樹的中序遍歷序列
同樣的長度可以用于分割后序遍歷序列,依次得到左右子樹的兩個序列
接下來對兩個子樹進行遞歸調用即可
演示代碼:
using namespace std;
typedef struct Node {
Node * lchild;
Node * rchild;
int data;
}Node;
int post[31]; //LRV
int in[31]; //LVR
Node *tree;
void buildTree(int p1, int p2, int i1, int i2, Node* &treeNode) {
if (treeNode==NULL)
{
treeNode = new Node();
}
if (p1>p2||i1>i2)
{
return;
}
//cout << “flag”<< endl;
treeNode->lchild = NULL;
treeNode->rchild = NULL;
treeNode->data = post[p2];
//cout <<post[p2] << endl;
int count = p1;
int i;
for ( i =i1 ; i <=i2; i++, count++)
{
if (post[p2] == in[i]) { //V found
break;
}
}
buildTree(p1, count – 1, i1, i – 1, treeNode->lchild);
buildTree(count, p2 – 1, i + 1, i2, treeNode->rchild);
}//注意邊界值
二叉樹的層次遍歷:
新建一個輔助隊列,將根節點入隊,然后出隊
對根節點進行訪問——同時,如果根節點存在后代的話,按照左右孩子的順序依次入隊
循環進行此操作,直至整個隊列徹底為空再停止
演示代碼:
queue<Node*>level;
level.push(tree);
vector<int>output;
while (!level.empty())
{
if (level.front()->data)
{
int number = level.front()->data;
// cout << number << endl;
output.push_back(number);
}
if (level.front()->lchild!=NULL)
{
level.push(level.front()->lchild);
}
if (level.front()->rchild!=NULL)
{
level.push(level.front()->rchild);
}
level.pop();
}