#include <iostream>
#include <sstream>
#include <set>
#include <vector>
using namespace std;
struct treeNode{
int data;
treeNode* leftChild;
treeNode* rightChild;
explicit treeNode(int d):data(d),leftChild(nullptr),rightChild(nullptr){}
};
class BinaryTree{
private:
treeNode* BuildTreeHelper(vector<int> &preOrder,int preStart,int preEnd,vector<int> &inOrder,int inStart,int inEnd){
if (preStart > preEnd || inStart > inEnd) return nullptr;
treeNode* root = new treeNode(preOrder[preStart]);
int index = inStart - 1;
while (index <= inEnd) {
// 找到真正的根
index++;
if (inOrder[index] == preOrder[preStart]){
int leftSize = index - inStart;
set<int> leftSIn,leftSPre;
for (int i = 0; i < leftSize; ++i) {
leftSIn.insert(inOrder[inStart+i]);
leftSPre.insert(preOrder[preStart+1+i]);
}
// 中序左子树遍历序列和前序遍历序列不同
if (leftSIn != leftSPre) continue;
root->leftChild = BuildTreeHelper(preOrder,preStart+1,preStart+leftSize,inOrder,inStart,index-1);
root->rightChild = BuildTreeHelper(preOrder,preStart+leftSize+1,preEnd,inOrder,index+1,inEnd);
break;
}
}
return root;
}
public:
treeNode* BuildTreeByPreAndIn(vector<int> &preOrder,vector<int> &inOrder){
if (preOrder.empty() || inOrder.empty()) return nullptr;
return BuildTreeHelper(preOrder,0,preOrder.size()-1,inOrder,0,inOrder.size()-1);
}
int SumLeftAndRight(treeNode* root){
int left = root->leftChild ? SumLeftAndRight(root->leftChild) + root->leftChild->data : 0;
int right= root->rightChild ? SumLeftAndRight(root->rightChild) + root->rightChild->data : 0;
return left + right;
}
void Inorder(treeNode* root,vector<int> &InOrderV){
if (root == nullptr) return;
Inorder(root->leftChild,InOrderV);
InOrderV.push_back(SumLeftAndRight(root));
Inorder(root->rightChild,InOrderV);
}
};
int main(){
string str;
getline(cin,str);
string part;
stringstream ss(str);
vector<int> inV,preV;
while (getline(ss,part,' ')) inV.push_back(stoi(part));
getline(cin,str);
ss.clear();
ss.str(str);
while (getline(ss,part,' ')) {
preV.push_back(stoi(part));
}
BinaryTree myBinaryTree;
treeNode* root = myBinaryTree.BuildTreeByPreAndIn(preV,inV);
vector<int> InOrderV;
myBinaryTree.Inorder(root,InOrderV);
for (auto x:InOrderV) {
cout<<x<<" ";
}
cout<<endl;
return 0;
}
使用前序遍历和中序遍历建立二叉树
于 2024-04-02 16:47:12 首次发布
本文介绍了一个使用C++编写的二叉树类,通过前序遍历和中序遍历的输入,构造二叉树并实现中序遍历输出节点值。方法包括递归的BuildTreeHelper函数和计算左右子树和的SumLeftAndRight函数。
摘要由CSDN通过智能技术生成