您的位置:首页 > 编程语言 > C语言/C++

[c++]已知二叉树的前序遍历与中序遍历结果(二叉树中不含重复数字),重构二叉树

2013-01-03 20:26 337 查看
比如说某二叉树

前序遍历结果:

12473568
中序遍历结果:

47215386
前序遍历就是先输出根节点,然后左节点,然后右节点

中序遍历就是先输出左节点,然后根节点,最后右节点

对于上面的二叉树我们可以这样分析:

12473568
47215386
其中绿色的为根结点,也就是1

然后通过中序遍历结果,得到 1 左边的(粉红)为左子树,右边的(浅蓝)为右子树,

左子树跟右子树在前序遍历的结果中,我们能根据左子树跟右子树的大小划分开来,

然后就得到了一颗根节点为 2 ,另一颗跟节点为 3 的二叉树了,

如此递归下去就能得到一颗完整的二叉树。

以下为c++实现的代码:

基于gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

/*已知二叉树的前序、中序遍历,重建二叉树*/

#include <iostream>
#include <list>
#include <sstream>
using namespace std;
struct tree{
int m_nValue;
tree *l_tree;
tree *r_tree;
}*root;

/*重建二叉树的主函数,通过递归重建
*f_begin:前序遍历头结点
*f_end :  前序遍历末尾节点
*m_begin:中序遍历头结点
*m_end:  中序遍历末尾节点
*/
tree *rebuild_tree(list<int>::iterator f_begin,list<int>::iterator f_end,list<int>::iterator m_begin,list<int>::iterator m_end);

/*显示重建后的二叉树*/
void show_tree(tree *root);

/*实现对list迭代器的整型加法,itr为迭代器,i为所加的整数*/
list<int>::iterator pluss(list<int>::iterator itr,int i);

/*计算出迭代器find_相对于begin的距离,范围是begin到end,并且把所找到的迭代器赋给res*/
int dist(list<int>::iterator begin,list<int>::iterator end,list<int>::iterator find_,list<int>::iterator &res);

/*convert是把string转换到list<int>容器内的转换函数*/
void convert(string &str,list<int> &i_list);

void free_tree(void);

/*前序l_front,中序l_mid*/
static list<int> l_front;
static list<int> l_mid;

/*list_head用于记录所创建的tree
*index用于记录tree指针所存的位置
*/
static tree *list_head[100];
static int tree_index;

int main()
{
string front;
string mid;

tree_index=0;

cout<<"请输入树的前序遍历序列(空格隔开):"<<endl;
getline(cin,front);

cout<<"请输入树的中序遍历序列(空格隔开):"<<endl;
getline(cin,mid);

convert(front,l_front);
convert(mid,l_mid);

/*这里不考虑.end()因为后面迭代的时候分段,list段内是没有.end()的,而,rebuild_tree是需要递归的函数,这样是为了保持一致性*/
root=rebuild_tree(l_front.begin(),--l_front.end(),l_mid.begin(),--l_mid.end());

cout<<"Show Tree"<<endl;
show_tree(root);
cout<<endl;
free_tree();
}

tree *rebuild_tree(list<int>::iterator f_begin,list<int>::iterator f_end,list<int>::iterator m_begin,list<int>::iterator m_end)
{
list<int>::iterator tmp,res;
list<int>::iterator tmp1,tmp2,tmp3;
int dis;
tree *root=(tree*)malloc(sizeof(tree));

list_head[tree_index]=root;
tree_index++;

dis=dist(m_begin,m_end,f_begin,res);
root->m_nValue=*f_begin;

cout<<"dis:"<<dis<<endl;

/*如果list内的数据已经被加入二叉树节点,那么把该list的节点赋值为-1,便于后面判断边界*/
*f_begin=-1;

/*---------------------如果有左子树,往左遍历-----------------------------*/
tmp=res;
/*---------------------如果dis为0,则说明没左子树-------------------------------*/
if(tmp==l_mid.begin()||dis==0)
{
root->l_tree=NULL;
}
else if(*(--tmp)==-1)
{
root->l_tree=NULL;
}
else
{
tmp1=pluss(f_begin,1);
tmp2=pluss(f_begin,dis);
tmp3=pluss(m_begin,dis-1);

root->l_tree=rebuild_tree(tmp1,tmp2,m_begin,tmp3);
}
/*-----------------------如果有右子树,往右遍历---------------------------*/

tmp=res;
/*如果搜索所得的结果为该中序遍历list段尾部,那么他的右子树为NULL*/
if(tmp==m_end)
{
root->r_tree=NULL;
}
else{
tmp++;
if(*tmp==-1|| tmp==l_mid.end())
{
root->r_tree=NULL;
}
else
{
tmp1=pluss(f_begin,dis+1);
tmp2=pluss(res,1);

root->r_tree=rebuild_tree(tmp1,f_end,tmp2,m_end);
}
}
/*------------------------------------------------------------------*/
cout<<"add node:"<<root->m_nValue<<endl;
return root;
}

list<int>::iterator pluss(list<int>::iterator itr,int i)
{
for(;i>0;i--)
{
itr++;
}
return itr;
}

int dist(list<int>::iterator begin,list<int>::iterator end,list<int>::iterator find_,list<int>::iterator &res)
{
res=find_;
int i=0;
end++;
do
{
if(*begin==*res)
{
res=begin;
return i;
}
i++;
begin++;
}while(begin!=end);

if(res!=l_mid.end())
*res=-1;

return -1;
}

void show_tree(tree *root)
{
cout<<root->m_nValue<<",";
if(root->l_tree)
{
show_tree(root->l_tree);
}
if(root->r_tree)
{
show_tree(root->r_tree);
}
}

void convert(string &str,list<int> &i_list)
{
int i;

stringstream strOutput(str);
for(;strOutput>>i;)
{
i_list.push_back(i);
}

}

void free_tree(void)
{
for(;tree_index>=0;tree_index--)
free(list_head[tree_index]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐