由中序与前序、中序与后序重建二叉树

来源:互联网 发布:数据流算法 编辑:程序博客网 时间:2024/06/01 21:07
由中序与前序、中序与后序重建二叉树

<span style="font-size:14px;">//节点类型template<class T>class TNode{public:TNode() { lchild = rchild = parent = nullptr; };T data;TNode<T>* lchild, *rchild, *parent;};</span>


一:已知前序与中序。
方法很简单,前序第一个节点为根节点,在中序中找到该节点。该位置左为左子树,右边为右子树。然后递归创建。
template<class T>TNode<T>* TriTree<T>::MakeRootByPre(const string& Pre, const int PreBegin, const int PreEnd,const string& In, const int InBegin, const int InEnd){assert("" != Pre || "" == In);if (!(PreBegin >= 0 && PreEnd >= 0 && InBegin >= 0 && InEnd >= 0)){return nullptr;}if (PreBegin > PreEnd || InBegin > InEnd ||(unsigned)PreEnd >= Pre.length() || (unsigned)InEnd >= In.length()){return nullptr;}char ChRoot = Pre[PreBegin];TNode<T>* pRoot = new TNode<T>();//暂时不考虑父节点  并且遍历结果以字符串显示pRoot->data = ChRoot;int nPos = FindInString(In,ChRoot,InBegin,InEnd);if (-1 == nPos){return nullptr;}int CountOfLeftTree = nPos - InBegin;//左子树节点个数pRoot->lchild = MakeRootByPre(Pre,PreBegin+1,PreBegin+ CountOfLeftTree,In,InBegin,nPos-1);//递归创建左子树pRoot->rchild = MakeRootByPre(Pre,PreBegin+CountOfLeftTree+1,PreEnd,In,nPos+1,InEnd);return pRoot;}
二:由后序与中序重建,方法与一相似,有节点在后序遍历末尾而已。
template<class T>TNode<T>* TriTree<T>::MakeRootByPost(const string& StrPost, const int PostBegin, const int PostEnd,const string& StrIn, const int InBegin, const int InEnd){//考虑父节点时可以再传一个参数即可//也可以写一个重建函数连接父节点assert(""!=StrPost&&""!=StrIn);if (PostBegin < 0 || PostEnd < 0 || InBegin<0 || InEnd<0 ||PostBegin>PostEnd || InBegin>InEnd||PostEnd>=StrPost.length()||InEnd>=StrIn.length()){return nullptr;}TNode<T>* pRoot = new TNode<T>();assert(nullptr!=pRoot);char ChRoot = StrPost[PostEnd];pRoot->data = ChRoot;int nPos = FindInString(StrIn, ChRoot,InBegin,InEnd);if (-1 == nPos){return nullptr;}int CountOfLeftTree = nPos - InBegin;pRoot->lchild = MakeRootByPost(StrPost,PostBegin,PostBegin+CountOfLeftTree-1,StrIn,InBegin,nPos-1);//注意边界pRoot->rchild = MakeRootByPost(StrPost,PostBegin+CountOfLeftTree,PostEnd-1,StrIn,nPos+1,InEnd);return pRoot;}
思想都比较简单,个人认为代码写得比较清晰,大家可以看完代码,了解思想后,再手撸一遍。
template<class T>int TriTree<T>::FindInString(const string& In, const char ChRoot, const int nBegin, const int nEnd){//参数为闭区间assert("" != In);if (!(nBegin >= 0 && nEnd >=0 && nEnd >= nBegin&&nEnd < (int)In.length())){return -1;}for (int i = nBegin; i <= nEnd; ++i){if (ChRoot == In[i]){return i;}}return -1;}



0 0
原创粉丝点击