二叉树的遍历方法有
1.迭代
2.递归
相比较来说迭代的实现较为复杂,后序遍历最为复杂。
给出了一些算法与代码
1.前序遍历
2.中序遍历
3.后序遍历
4.不用栈的中序遍历
前序遍历为:访问根节点、访问左子树、访问右子树;
中序遍历为:访问左子树、访问根节点、访问右子树。
后序遍历为:访问左子树、访问右子树、访问根节点。
由于前序遍历和中序遍历比较简单就给出伪代码
PREORDER-TREE-WALK(x)//前序遍历
1. let s be a new stack
2. while(x!=NULL||!s.empty())
3. while p!=NULL
4. push(x)
5. printf x->data//区别在这里
6. x=x->left
7. else s!.empty()
8. x=s.top()
9. pop(x)
10. x=x->right
INORDER-TREE-WALK(x)//中序遍历
1. let s be a new stack
2. while(x!=NULL||!s.empty())
3. while p!=NULL
4. push(x)
5. x=x->left
6. else s!.empty()
7. x=s.top()
8. printf x->data
9. pop(x)
10. x=x->right
3.后序遍历
void PostOrderTraverse(BiTree T)
{
SqStack S;
BiTree p = T;
InitStack(S);
while (p || !StackEmpty(S))
{
if(p)
{
if (p->visitcount != 2)
{
p->visitcount = 1; //遍历左子节点赋值1
Push(S, p);
}
p = p->lchild;
}
else
{
Pop(S, &p);
if(p->visitcount == 2)
{
printf("%c ", p->data);
}
else
{
p->visitcount++; //右子将要被遍历,visitcount++。无论右子节点是否存在,值都会为2,
//即使存在父节点也将在若干轮后被输出
Push(S, p);
}
p = p->rchild;
}
}
}
4.不用栈的中序遍历
//迭代的不用栈的中序遍历
void BinaryTree_recurse_non_stack_in_order_visit(Node* root)
{
while ( root != NULL )
{
while ( root->left != NULL &&!root->left->visited )
{
//一路向左
root = root->left;
}
if ( !root->visited )//节点没被输出过,那就把他输出吧
{
cout<<root->data<<"\t";
root->visited=true;
}
if ( root->right != NULL &&!root->right->visited )
{
//右子树
root = root->right;
}
else
{
//左右子树都到头了 那我回去吧= =
root = root->parent;
}
}
}
先序遍历二叉树void PreorderTraverse_1(BiTree T)
{
BiTree p;
SqStack S;
InitStack(S);
Push(S, T); //根指针进栈
while(!StackEmpty(S))
{
while(GetTop(S, &p) && p)
{
printf("%c ", p->data);
Push(S, p->lchild);
}
Pop(S, &p); //空指针退栈
if(!StackEmpty(S))
{
Pop(S, &p); //根结点出栈
Push(S,p->rchild); //右孩子进栈
}
}
}
中序遍历二叉树
void InOrderTraverse_1(BiTree T)
{
SqStack S;
BiTree p;
InitStack(S);
Push(S,T);
while (!StackEmpty(S))
{
while (GetTop(S,&p) && p)
{
Push(S,p->lchild); //向左走到尽头
}
Pop(S,&p); //空指针退栈
if (!StackEmpty(S))
{
Pop(S,&p);
printf("%c ", p->data);
Push(S,p->rchild);
}
}
}