前序中序、中序后序二叉树的建立

上了大学刚开始学编程语言,一开始忙头乱脚,什么都不会。之前看到一篇关于求职的文章,提到说写博客,然后应试者与主考官聊到博客,说自己写了很多有关于编程的东西,今天我也要开始写了!


 
 
/*关于二叉树,怎么去建树,一开始自己想来想去,给你一个前序和中序,
或者后序中序,到底该怎么建,一开始自己也非常的糊涂,自己想了大概
天,实在是不太明白,结果在网上一查,哦,原来是这样的,采用递归的
方法去建树,数据结构的书本中只是给了遍历的算法,怎么建树还要靠自己*/
//前序、中序建树
/*根据前序和中序的特点,前序序列pre的第一个字符pre[0]便是根结点,然后用<string>
封装的查找函数find()去查找根结点在中序序列in的位置,在中序序列中根结点的左边串
便是左子树,根结点右边的串便是右子树,然后用<string>封装的拷贝复制函数substr()
分别把左子树和右子树记下来;同理,在前序序列中,把左子树和右子树分别分开记下,
之后对应的把分开的左右子树有利用递归继续分下去,每次找到根结点便new一个新结点
直到pre的长度为0时结束*/
void createTree(BiNode<T>* &t, string pre,string in) //前序,中序
{
if(pre.length()==0) //当序列的长度为0时,给根赋NULL
{
t=NULL;
}
if(pre.length()!=0)
{
t=new BiNode<T>(pre[0]); //给(子)树根结点实例化
int index=in.find(pre[0]); //查找根结点在中序串中的位置
string in_lchild=in.substr(0, index); //中序的左子树
string in_rchild=in.substr(index+1); //中序的右子树
string pre_lchild=pre.substr(1, index); //前序的左子树
string pre_rchild=pre.substr(index+1); //前序的右子树
if(t!=NULL) //当t不为空时,利用递归创建子树
{
createTree(t->lchild,pre_lchild,in_lchild);
createTree(t->rchild,pre_rchild,in_rchild);
}
}
}
/*后序和中序建树思想及大致过程同上,不过要注意的是记录后序的左右子树要小心,
否则记错就会失败了*/
void createTree(BiNode<T>* &t, string post,string in) //post后序,in中序
{
if(post.length()==0)
{
t=NULL;
}
if(post.length()!=0)
{

int dex=post.length()-1; //根结点在后序序列的位置
t=new BiNode<T>(post[dex]); //新建一个根结点
int index=in.find(post[dex]); //查找根结点在中序序列的位置
string lchild_in=in.substr(0, index);
string rchild_in=in.substr(index+1);
string lchild_post=post.substr(0, index);
string rchild_post=post.substr(index,rchild_in.length());
if(t!=NULL)
{
createTree(t->lchild,lchild_post,lchild_in);
createTree(t->rchild,rchild_post,rchild_in);
}
}
}
//完整代码如下
#include<string>
#include<iostream>
#include<stack>
using namespace std;
//二叉链表表示二叉树
template<class T>
class BiNode
{
public:
T data;//节点数据
BiNode * lchild;//左孩子
BiNode * rchild;//右孩子
BiNode();
BiNode(T d){ data=d; } //new一个结点的时候就给其数据域赋值
~BiNode(){}
void createTree(BiNode<T>* &t, string pre,string in) //前序,中序
{
if(pre.length()==0)
{
t=NULL;
}
if(pre.length()!=0)
{
t=new BiNode<T>(pre[0]);
int index=in.find(pre[0]);
string in_left_str=in.substr(0, index);
string in_right_str=in.substr(index+1);
string pre_left_str=pre.substr(1, index);
string pre_right_str=pre.substr(index+1);
if(t!=NULL)
{
createTree(t->lchild,pre_left_str,in_left_str);
createTree(t->rchild,pre_right_str,in_right_str);
}
}
}
void preOrder(BiNode<T> *t) //前序遍历
{
if(t==NULL)
{
return ;
}
if(t!=NULL)
{
cout<<t->data;
preOrder(t->lchild);
preOrder(t->rchild);
}
}
void inOrder(BiNode<T> *t) //中序遍历
{
if(t==NULL)
{
return ;
}
if(t!=NULL)
{
inOrder(t->lchild);
cout<<t->data;
inOrder(t->rchild);
}
}

};
int main()
{
BiNode<char> *t=NULL;
string pre="ABDFGCEH";
string in="BFDGACEH";
t->createTree(t,pre,in);
cout<<"前序遍历"<<endl;
t->preOrder(t);
cout<<endl;
cout<<"中序遍历"<<endl;
t->inOrder(t);
cout<<endl;
return 0;
}

/*总体来说,这个学期真的像老师那样所说,多敲,代码能力就会提高,写这个递归的
二叉树让我对C++的指针更了解,对递归的用法也更深刻,写完这几个代码,后面我还
特意的回去看了小李子主演的《盗梦空间》和《禁闭岛》,感觉他们演电影就是在递归*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值