I. 总述
对于树的储存方式来讲,遍历方法可谓是树的精髓,没有一个好的遍历方法,一颗二叉树就是没有意义的。
II. 常见的三种二叉树遍历方法
A. 先序 先输出当前结点的值,若是当前结点由左儿子,则遍历左儿子,左儿子遍历完毕后,接着遍历右儿子。
B. 中序 若是当前结点由左儿子,则遍历左儿子,左儿子遍历完毕后,输出当前结点的值,接着遍历右儿子。
C. 后序 先遍历左右儿子,最后输出值。
III. 先序、中序、后序的递归建立
结点类型
typedefstruct node
{
int data;
struct node *lchild;
struct node *rchild;
}BTree ,*BiTree ;
先序:
void PreOder ( BiTree T )
{
if( T!=NULL )
{
cout<<T->data;
PreOder(T->lchild);
PreOder(T->rchild);
}
}
中序
void InOder ( BiTree T )
{
if( T!=NULL )
{
PreOder(T->lchild);
cout<<T->data;
PreOder(T->rchild);
}
}
后序
void PostOder ( BiTree T )
{
if( T!=NULL )
{
PreOder(T->lchild);
PreOder(T->rchild);
cout<<T->data;
}
}
IV. 先序、中序、后序的非递归建立
为什么要使用非递归?
递归虽然很简洁,但并不是所有程序都能使用递归,而且递归的可读性极差,且执行效率不高,就此可以将递归程序设计成非递归的程序。
结点类型
typedefstruct node
{
int data;
struct node *lchild;
struct node *rchild;
}BTree ,*BiTree ;
先序
voidPreOder ( BiTree T )
{
BiTree stack[1000],p; //定义结点类型指针栈
int top=-1;
if( T==NULL )
return ;
p = T;
while( !(p==NULL&&top==-1))
{
while( p!=NULL ) //先左儿子
{
cout<<p->data;
top++;
stack[top]=p;
p=p->lchild;
}
if( top<0 )
return;
else //后右儿子
{
p = stack[top];
top--;
p=p->rchild;
}
}
}
中序
中序遍历只需将先序的“cout<<p->data;”移至p = stack[top];和p=p->rchild;间即可。
后序
voidPreOder ( BiTree T )
{
BiTree stack[1000],p; //定义结点类型指针栈
int top=-1;
if( T==NULL )
return ;
p = T;
while( !(p==NULL&&top==-1))
{
while( p!=NULL ) //左孩子压栈
{
top++;
stack[top]=p;
p=p->lchild;
}
if( top>-1 ) //栈不为空
if( stack[top]>0 ) //第一次在栈中
{
p = stack[top]->rchild; //指向右孩子
stack[top] = -stack[top]; //置逆值,相当于第一次出栈,第二次 进栈,值改变了
}
else
{
p = -stack[top]; //第二次出栈
top--;
cout<<p->data;
p=NULL;
}
}
}