已知二叉树的中序和前序序列(或后序)求解树

简介: 转自:http://www.cnblogs.com/bmrs/archive/2010/08/19/SloveTree.html 这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。

转自:http://www.cnblogs.com/bmrs/archive/2010/08/19/SloveTree.html

这种题一般有二种形式,共同点是都已知中序序列。如果没有中序序列,是无法唯一确定一棵树的,证明略。

一、已知二叉树的前序序列和中序序列,求解树。

1、确定树的根节点。树根是当前树中所有元素在前序遍历中最先出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

二、已知二叉树的后序序列和中序序列,求解树。

1、确定树的根。树根是当前树中所有元素在后序遍历中最后出现的元素。

2、求解树的子树。找出根节点在中序遍历中的位置,根左边的所有元素就是左子树,根右边的所有元素就是右子树。若根节点左边或右边为空,则该方向子树为空;若根节点左边和右边都为空,则根节点已经为叶子节点。

3、递归求解树。将左子树和右子树分别看成一棵二叉树,重复1、2、3步,直到所有的节点完成定位。

举例说明:根据已知求解二叉树

中序序列 HLDBEKAFCG
后序序列 LHDKEBFGCA

1、在后序序列LHDKEBFGCA中最后出现的元素为A,HLDBEK|A|FCG
2、在后序序列LHDKEB中最后出现的元素为B,HLD|B|EK|A|FCG
3、在后序序列LHD中最后出现的元素为D,HL|D|B|EK|A|FCG
4、在后序序列LH中最后出现的元素为H,H|L|D|B|EK|A|FCG
5、在后序序列KE中最后出现的元素为E,H|L|D|B|E|K|A|FCG

5、在后序序列FGC中最后出现的元素为C,H|L|D|B|E|K|A|F|C|G
6、所有元素都已经定位,二叉树求解完成。

                 A
              /     \
             B       C
            / \     /  \
           D  E     F   G
          /    \
         H      K                    
          \                         
           L          

 

Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->  1 /*
    功能: 1.利用树的前序和中序序列创建树
          2.利用树的后序和中序序列创建树
*/
#include <iostream>
#include <cstring>
using namespace std;

char pre[50] = "ABDHLEKCFG";        //前序序列
char mid[50] = "HLDBEKAFCG";        //中序序列
char post[50] = "LHDKEBFGCA";        //后序序列

typedef struct _Node
{
    char v;
    struct _Node *left;
    struct _Node *right;
}Node, *PNode;

void PostTravelTree(PNode pn);        //树的后序递归遍历
void PreTravelTree(PNode pn);        //树的前序递归遍历
void PreMidCreateTree(PNode &pn, int i, int j, int len);        //利用前序中序序列创建树
void PostMidCreateTree(PNode &pn, int i, int j, int len);        //利用后序中序序列创建树
int Position(char c);                //确定c在中序序列mid中的下标,假设树的各个节点的值各不相同


int main() 
{ 
    PNode root1 = NULL, root2= NULL;

    PreMidCreateTree(root1, 0, 0, strlen(mid));
    PostTravelTree(root1); cout<<endl;    
    PostMidCreateTree(root2, strlen(post)-1, 0, strlen(mid));
    PreTravelTree(root2); cout<<endl;    

    return 0;
}


int Position(char c)
{
    return strchr(mid,c)-mid;
}


/*  利用前序中序序列创建树,参考了http://hi.baidu.com/sulipol/blog/item/f01a20011dcce31a738b6524.html
 *的实现,代码十分简洁,竟然只有短短的"令人发指"的8行,递归实在太彪悍了!!!!!!!!!!!!!!!!!!!!!
 *        i: 子树的前序序列字符串的首字符在pre[]中的下标
 *        j: 子树的中序序列字符串的首字符在mid[]中的下标
 *      len: 子树的字符串序列的长度
 */
void PreMidCreateTree(PNode &pn, int i, int j, int len)
{
    if(len <= 0)
        return;
    
    pn = new Node;
    pn->v = pre[i];
    int m = Position(pre[i]);
    PreMidCreateTree(pn->left, i+1, j, m-j);            //m-j为左子树字符串长度
    PreMidCreateTree(pn->right, i+(m-j)+1, m+1, len-1-(m-j));    //len-1-(m-j)为右子树字符串长度
}


/*  利用后序中序序列创建树
 *        i: 子树的后序序列字符串的尾字符在post[]中的下标
 *        j: 子树的中序序列字符串的首字符在mid[]中的下标
 *      len: 子树的字符串序列的长度
 */
void PostMidCreateTree(PNode &pn, int i, int j, int len)
{
    if(len <= 0)
        return;

    pn = new Node;
    pn->v = post[i];
    int m = Position(post[i]);
    PostMidCreateTree(pn->left, i-1-(len-1-(m-j)), j, m-j);//注意参数:m-j左子树的长度,len-1-(m-j)右子树的长度
    PostMidCreateTree(pn->right, i-1, m+1, len-1-(m-j));
}


void PostTravelTree(PNode pn)        //后序递归遍历
{
    if(pn)
    {
        PostTravelTree(pn->left);    
        PostTravelTree(pn->right);
        cout<<pn->v<<" ";
    }
}


void PreTravelTree(PNode pn)        //前序递归遍历
{
    if(pn)
    {
        cout<<pn->v<<" ";
        PreTravelTree(pn->left);    
        PreTravelTree(pn->right);
    }
}

 

 

相关文章
【Vite】Vite设置好了Proxy,但接口却404!解决方案来了!
前言 最近在做一个Vue3+Vite+TypeScript的项目,进行一番网上冲浪后,参考了众多🐴友的方案,配置完vite.config.ts准备开始与后端的同学开始联调,发现无论怎么样都是404,然后就开始了一步步的排查!
6269 0
|
Python
Python面试题大全总结
Python面试题大全总结
2773 0
Python面试题大全总结
|
设计模式 负载均衡 监控
深入理解后端开发中的微服务架构
在现代软件开发领域,微服务架构已经成为一种流行的设计模式。本文将探讨微服务的基本概念、优势与挑战,并通过实例展示如何在实际项目中应用微服务架构。无论是初学者还是经验丰富的开发者,都能从中获得启发和实用技巧。
166 7
|
存储 机器学习/深度学习 人工智能
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
数据结构学习笔记——图的存储结构(邻接矩阵和邻接表)
|
数据采集 机器学习/深度学习 算法
Python实现LightGBM分类模型(LGBMClassifier算法)项目实战
Python实现LightGBM分类模型(LGBMClassifier算法)项目实战
|
运维 监控 Unix
htop命令详解
`htop`是Unix-like系统的一款增强版进程查看器,基于ncurses,提供实时系统监控、交互式导航、彩色界面和多核支持。用户可通过键盘或鼠标操作,如排序、搜索、过滤进程,直接发送信号(如`F9`杀进程)等。常用快捷键包括`P`(按CPU排序)、`F3`(搜索进程)、`F2`(设置)和`F10`(退出)。它是`top`的现代替代品,提升资源管理和故障排查效率。
718 2
|
算法 安全
二叉树的基本操作(如何计算二叉树的结点个数,二叉树的高度)
二叉树的基本操作(如何计算二叉树的结点个数,二叉树的高度)
680 0
|
存储 SQL NoSQL
【面试题系列】混合夺命21问,你能扛到第几问?
目录 1. Mysql索引在什么情况下会失效 2. MySql的存储引擎InnoDB与MyISAM的区别 3. mysql在项目中的优化场景,慢查询解决等 4. Mysql有什么索引,索引模型是什么 5. B-树与B+树的区别?为什么不用红黑树 6. Mysql主从同步怎么做 7. 乐观锁与悲观锁的区别? 8. 聊聊binlog日志 9. Redis 持久化有哪几种方式,怎么选? 9.1 AOF 持久化 9.2 RDB 9.3 如何选择RDB和AOF 10. Redis 主从同步是
609 0
【面试题系列】混合夺命21问,你能扛到第几问?
|
机器学习/深度学习 C++ 容器
二叉树创建和遍历(C++实现)
树(Tree)是n(n≥0)个节点的有限集。在任意一棵树中有且仅有一个特定的称为根(Root)的节点;当n>1时,其余节点可分m(m>0)为个互不相交的有限集T1,T2,...,Tm;其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。 二叉树(Binary Tree)是一种特殊的有序树型结构,所有节点最多只有2棵子树。
1050 0
|
存储 弹性计算 固态存储
阿里云服务器ECS与轻量应用服务器最新收费标准及活动价格表
本文整理汇总了阿里云服务器ECS与轻量应用服务器最新收费标准及活动价格表,可供新手用户了解云服务器与轻量应用服务器的收费标准及最新活动价格情况,从而根据自己的情况选择合适的云服务器或轻量应用服务器。
944 0
阿里云服务器ECS与轻量应用服务器最新收费标准及活动价格表