由中序与前序、中序与后序重建二叉树
2016-03-15 19:45
176 查看
由中序与前序、中序与后序重建二叉树
一:已知前序与中序。
方法很简单,前序第一个节点为根节点,在中序中找到该节点。该位置左为左子树,右边为右子树。然后递归创建。
<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; }
相关文章推荐
- Android 启动网络学习小笔记(未完善学到哪更到哪)
- iOS 多视图—视图切换之代码块传参切换
- Fling——K
- 对Spring的IoC和DI最生动的解释
- Java EE 项目启动加载顺序
- mysql重置root密码
- 桶式排序
- Linux第一章第二章学习笔记
- Speex编解码在Android上实现
- 数据缓存设计方案-------一致性哈希
- Android Studio下简单编译AIDL方法
- 【Android进阶】Android自定义组件之自动换行View,以TextView为例
- 2016-春季校招面试笔试mark
- 快速排序
- 优化的快速排序
- 聚内核与微内核
- 讲述一下runtime的概念,message send如果寻找不到相应的对象,会如何进行后续处理 ?
- 06 GPUImage滤镜效果
- Poj 2892 Tunnel Warfare
- HDU.1023 Train Problem II【大数除法、卡特兰数】--用于求出栈的n种方式(3.15)