使用前序遍历和中序遍历建立二叉树

本文介绍了一个使用C++编写的二叉树类,通过前序遍历和中序遍历的输入,构造二叉树并实现中序遍历输出节点值。方法包括递归的BuildTreeHelper函数和计算左右子树和的SumLeftAndRight函数。
摘要由CSDN通过智能技术生成
#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值