遍历序列确定二叉树

二叉树(中序,先序,后序,层次遍历) 

定理:已知二叉树前序,中序序列可唯一确定一颗二叉树(证明略)

同理:可以通过(中序,先序),(后序,中序),(层次,中序)确定一颗二叉树。

二叉树个数计数: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;
}
}

 

 

posted on 2011-09-06 20:47  youngkang  阅读(1346)  评论(0)    收藏  举报