从两种遍历还原二叉树

 

节点定义 

template<typename T>
class TreeNode {
public:
    T data;
    TreeNode<T>* left, * right;
    TreeNode() :left(nullptr), right(nullptr) {}
    TreeNode(const T& data) :data(data), left(nullptr), right(nullptr) {}
};

二叉树

#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<string>
using namespace std;
template<typename T>
class BinaryTree {
private:
    TreeNode<T>* root;
    typedef typename vector<T>::iterator Iter;
    static TreeNode<T>* build_tree_with_pre_in_order(Iter,Iter,Iter,Iter);
    static TreeNode<T>* build_tree_with_in_post_order(Iter, Iter, Iter, Iter);
    static TreeNode<T>* build_tree_with_level_in_order(vector<T>,vector<T>,int,int);
public:
    BinaryTree();
    static TreeNode<T>* build_tree_with_pre_in_order(vector<T>, vector<T>);
    static TreeNode<T>* build_tree_with_in_post_order(vector<T>, vector<T>);
    static TreeNode<T>* build_tree_with_level_in_order(vector<T>,vector<T>);
};

前序遍历+中序遍历

/**
 * 前序遍历和中序遍历创建二叉树
 * @param pre_start 前序迭代器
 * @param pre_end 前序末尾
 * @param in_start 中序迭代器
 * @param in_end 中序末尾
 * @return 根节点
 */
typedef typename vector<T>::iterator Iter;
template<typename T>
TreeNode<T>* BinaryTree<T>::build_tree_with_pre_in_order(Iter pre_start,Iter pre_end,Iter in_start,Iter in_end)
{
    //没有节点了
    if (pre_start == pre_end) {
        return nullptr;
    }
    //当前节点
    T val = *pre_start;
    auto* rt = new TreeNode<T>(val);
    //找到中序遍历中当前节点位置
    Iter val_pos = find(in_start, in_end, val);
    rt->left = build_tree_with_pre_in_order(pre_start + 1, pre_start + (val_pos - in_start) + 1, in_start, val_pos);
    rt->right = build_tree_with_pre_in_order(pre_start + (val_pos - in_start) + 1, pre_end, val_pos + 1, in_end);
    return rt;
}

/**
 * 根据前序遍历和中序遍历建树
 * @param pre_order 前序遍历
 * @param in_order 中序遍历
 * @return 根节点
 */
template<typename T>
TreeNode<T>* BinaryTree<T>::build_tree_with_pre_in_order(vector<T> pre_order, vector<T> in_order)
{
    return build_tree_with_pre_in_order(pre_order.begin(), pre_order.end(), in_order.begin(), in_order.end());
}

中序遍历+后序遍历

/**
 * 前序遍历和中序遍历创建二叉树
 * @param in_start 中序迭代器
 * @param in_end 中序末尾
 * @param post_start 后序迭代器
 * @param post_end 后序末尾
 * @return 根节点
 */
template<typename T>
typedef typename vector<T>::iterator Iter;
TreeNode<T>* BinaryTree<T>::build_tree_with_in_post_order(Iter in_start, Iter in_end, Iter post_start, Iter post_end)
{
    //没有节点了
    if (in_start == in_end) {
        return nullptr;
    }
    //当前节点
    T val = *(post_end - 1);
    auto* rt = new TreeNode<T>(val);
    //找到中序遍历中当前节点位置
    Iter val_pos = find(in_start, in_end, val);
    rt->left = build_tree_with_in_post_order(in_start, val_pos, post_start, post_start + (val_pos - in_start));
    rt->right = build_tree_with_in_post_order(val_pos + 1, in_end, post_start + (val_pos - in_start), post_end - 1);
    return rt;
}
/**
 * 根据中序遍历和后序遍历建树
 * @param in_order 中序遍历
 * @param post_order 后序遍历
 * @return 根节点
 */
template<typename T>
TreeNode<T>* BinaryTree<T>::build_tree_with_in_post_order(vector<T> in_order, vector<T> post_order)
{
    return build_tree_with_in_post_order(in_order.begin(), in_order.end(), post_order.begin(), post_order.end());
}

中序遍历+层序遍历

/**
 * 根据中序遍历和后序遍历建树
 * @param in_order 中序遍历
 * @param post_order 后序遍历
 * @param in_start 中序遍历的开始位置
 * @param in_end 中序遍历结束位置
 * @return 根节点
 */
template<typename T>
TreeNode<T> *BinaryTree<T>::build_tree_with_level_in_order(
        vector<T> level_order,
        vector<T> in_order,
        int in_start,
        int in_end) {
    if(in_start>=in_end){
        return nullptr;
    }
    //当前节点
    T val=level_order[0];
    auto* rt=new TreeNode<T>(val);
    int val_pos=in_start;
    //找到当前节点值在中序遍历中的位置
    while(val_pos<in_end&&in_order[val_pos]!=val){
        ++val_pos;
    }
    //左子树的层序遍历
    vector<T> left;
    //右子树的层序遍历
    vector<T> right;
    for(size_t i=1;i<level_order.size();++i){
        int j;
        //中序遍历中,当前节点值左边的是左子树
        for(j=0;j<val_pos;++j){
            if(in_order[j]==level_order[i]){
                left.push_back(level_order[i]);
                break;
            }
        }
        //中序遍历中,当前节点值右边的是右子树
        if(j>=val_pos){
            right.push_back(level_order[i]);
        }
    }
    rt->left=build_tree_with_level_in_order(left,in_order,in_start,val_pos);
    rt->right=build_tree_with_level_in_order(right,in_order,val_pos+1,in_end);
    return rt;
}
/**
 * 用层序遍历和中序遍历建树
 * @param level_order 层序遍历
 * @param in_order 中序遍历
 * @return 根节点
 */
template<typename T>
TreeNode<T> *BinaryTree<T>::build_tree_with_level_in_order(vector<T> level_order, vector<T> in_order) {
    return build_tree_with_level_in_order(level_order,in_order,0,in_order.size());
}

只从前序遍历不能建树反例

只从中序遍历不能建树反例

只从后序遍历不能建树反例

前序遍历和后序遍历不能建树反例

前序遍历和层序遍历不能建树

后序遍历和层序遍历不能建树

发布了93 篇原创文章 · 获赞 83 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_39942341/article/details/102468460