/遍历之章/
/*前序遍历*/
void PreOrderTraverse_1(BiTree T)
{
if (T)
{
printf("%3c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
/*if(T)与 PreOrder(T->lchild)的奥秘:当T->lchild为空时,
执行下一条语句,自己好好想想呗*/
/*先序遍历非递归-栈实现*/
/*1、持续访问左孩子,全部入栈,直到不存在,栈顶元素(指针)出栈
2、将该指针指向的右孩子,看看这个右孩子有没有左孩子:循环12*/
void PreOrderTraverse_2(BiTree T)
{
BiTree Stack[MAXSIZE];
int top = 0;
BiNode *p ; p = T;
while( p || top > 0){
while(p){
printf("%2c ", p->data);
Stack[top++] = p; //p入栈
p = p->lcihld;
}
if(top>0){
p = Stack[--top]; //1、
p = p->rchild;
}
}
}
/*中序遍历递归实现*/
void InOrderTraverse_1(BiTree T)
{
if(T)
{
InOrderTraverse(T->lchild);
printf("%c \n", T->data);
InOrderTraverse(T->rchild);
}
}
/*中序遍历-非递归-栈实现*/
void InOrderTraverse_2(BiTree T)
{
BiTree Stack[MAXSIZE];
int top =0;
BiTree p; p = T;
while( p || top > 0 )
{
while(p)
{
Stack[top++] = p;
p = p->lchild;
}
if(top > 0)
{
p = Stack[--top] ;
printf("%c\n", p->data);
p = p->rchild;
}
}
}
/*结合中序图:要先把所有左子树入栈,下面的“if”,我们还是按照
假想补全的方法:因为此时栈顶的是一个没有左子树的结点G,所以相当于
G已经遍历了左子树,输出NULL,顶点出栈,输出值G,再转到右子树:
所以有下面“if语句”的p = p->rchild ==NULL,只不过G的右子树为空,输出为NULL,
继续在if()里出栈将D的地址赋予,D右子树也为空,继续在if()里出栈将B输出,
B的右子树为E,回到while ,我们试图找到E的左子树,事实上,如果E有左子树的话
while()会将所有左孩子像ABDG一样全部入栈。所以整个函数的设计完全是按照左中右的
巧妙顺序来设计的。,*/
/*后序遍历*/
void PostOrderTraverse_1(BiTree T)
{
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%2c ",T->data);
}
}
void PreOrderTraverse_2(BiTree T)
{
BiTree Stack[MAXSIZE];
BiNode *p,*q; p = T; q = NULL;
int top = 0;
while( p || top > 0 ) {
while(p) {
Stack[top++] = p;
p = p->lchild;
} /*while*/
if( top>0 ) {
p = Stack[ top - 1];
if ( p->rchild == q || p->rchild == NULL){
printf("%2c ",p->data);
q = p; // 第一次q指向G
p = NULL; //上面的while 不能执行
top--;
}else
p = p->rchild; //1、
}
}
}