遍历序列确定二叉树
二叉树(中序,先序,后序,层次遍历)
定理:已知二叉树前序,中序序列可唯一确定一颗二叉树(证明略)
同理:可以通过(中序,先序),(后序,中序),(层次,中序)确定一颗二叉树。
二叉树个数计数:n节点不同二叉树个数
n s
0 1
1 1
2 2
3 5
已知一个前序序列 1,2,3.....n,那么对此前序排列得到的不同中序序列即是不同二叉数个数,那1-n依次进栈,得到不同出栈方式s,s就是中序方式数。
不同二叉树数量:bn=C(2n,n)/(n+1)

//通过前序和中序序列确定一棵二叉树
template<class T> int Location(T *array,int n,T &item);
template<class T>
void Set_Tree_By_PreoderAndInorder(T *prelist,T *inlist,int n,tree<T> &mytree)
{
//非递归算法
tree_node<T> *cur,*p;
int position=0;
stack_list<tree_node<T> *> stack;
//初始化,visit数组,用于记录 inorder序列中已访问过元素
int *visit=new int[n];
memset(visit,0,n*sizeof(int));
p=new tree_node<T>;
if (!prelist||!p)
{
cout<<"error:prelist null! or new node error"<<endl;
return ;
}
//初始化根结点
p->lchild=p->rchild=NULL;
p->value=prelist[0];
mytree.set_root(p);
stack.push(p);
//依次遍历preorder序列
for(int i=1;i<n;)
{
cur=stack.Top();
position=Location<T>(inlist,n,cur->value);
if (position<0)
{
cout<<"error:inorder and preorder not match"<<endl;
return ;
}
visit[position]=1;
if (position>0 && visit[position-1]==0)
{
//左子树构建
p=new tree_node<T>;
p->lchild=p->rchild=NULL;
p->value=prelist[i++];
cur->lchild=p;
stack.push(p);
}
else if (visit[position+1]==0)
{
//右子树构建
p=new tree_node<T>;
p->lchild=p->rchild=NULL;
p->value=prelist[i++];
cur->rchild=p;
stack.push(p);
}else
{
//叶子节点,出栈
stack.pop();
}
}
}
//定位array中item位置
template<class T> int Location(T *array,int n,T &item)
{
int i=0;
for (i=0;i<n;i++)
{
if (array[i]==item)
return i;
}
if (i==n)
return -1;
}
//中序,先序确定二叉树递归算法
template<class T> tree_node<T> * PreoderAndInorder(T *prelist,int i,int j,T*inlist,int k,int m);
template<class T>
void Set_Tree_By_PreoderAndInorder_recursion(T *prelist,T *inlist,int n,tree<T> &mytree)
{
tree_node<T> *root=PreoderAndInorder<T>(prelist,0,n-1,inlist,0,n-1);
mytree.set_root(root);
}
//其中i,j是prelist段下标,k,m 是inlist段下标
template<class T>
tree_node<T> * PreoderAndInorder(T *prelist,int i,int j,T*inlist,int k,int m)
{
if(k>m)
{
return NULL;
}
else
{
tree_node<T> *p=new tree_node<T>;
if (!p)
{
cout<<"error:apply new tree node"<<endl;
return NULL;
}
p->lchild=p->rchild=NULL;
p->value=prelist[i];
//在inlist中序序列中找出先序首节点位置
int x=0;
for (x=k;x<=m;x++)
{
if (inlist[x]==p->value)
break;
}
//没找到,错误
if (x>m)
{
cout<<"error: preorder and inorder not match"<<endl;
return NULL;
}
p->lchild=PreoderAndInorder<T>(prelist,i+1,i+x-k,inlist,k,x-1);
p->rchild=PreoderAndInorder<T>(prelist,i+x-k+1,j,inlist,x+1,m);
return p;
}
}