您的位置:首页 > 其它

二叉树的递归和非递归遍历方法

2017-09-23 20:03 120 查看
二叉树的遍历方法分三种:前序,中序和后序。
前序遍历:根,左子树,右子树;
中序遍历:左子树,根,右子树;
后序遍历:左子树,右子树,根;


//二叉树的递归前序遍历
void PreOrder(BtNode *ptr)
{
if(ptr != NULL)
{
printf("%c ",ptr->data);
PreOrder(ptr->leftchild);
PreOrder(ptr->rightchild);
}
}
//二叉树的递归中序遍历
void InOrder(BtNode *ptr)
{
if(ptr != NULL)
{
InOrder(ptr->leftchild);
printf("%c ",ptr->data);
InOrder(ptr->rightchild);
}
}
//二叉树的递归后序遍历
void PastOrder(BtNode *ptr)
{
if(ptr != NULL)
{
PastOrder(ptr->leftchild);
PastOrder(ptr->rightchild);
printf("%c ",ptr->data);
}
}


二叉树的非递归调用主要是利用栈先进后出的特点遍历整个树,将需要打印的结点在栈内进行出栈和入栈操作。


//非递归前序遍历
void NicePreOrder(BtNode *ptr)
{
if(ptr == NULL) return ;
Init_Stack(&st);
push(&st,ptr);         //将根节点入栈
while(!empty(&st))      //当栈为空时,表示整个树遍历完成
{
ptr = top(&st); pop(&st);
printf("%c ",ptr->data);      //第一次将根节点打印
if(ptr->rightchild != NULL)//为了让左孩子先打印,要将右孩子的元素放在栈底
push(&st,ptr->rightchild);
if(ptr->leftchild != NULL)
push(&st,ptr->leftchild);
}
}
//非递归中序遍历
void NiceInOrder(BtNode *ptr)
{
if(ptr == NULL) return ;
Stack st;
Init_Stack(&st);

while(ptr != NULL || !empty(&st))
{
while(ptr != NULL)
{
push(&st,ptr);    //先将左子树遍历并入栈,最后一个入栈的即为最左边的孩子节点
ptr = ptr->leftchild;
}
ptr = top(&st); pop(&st); //将最左边的孩子节点出栈
printf("%c ",ptr->data);
ptr = ptr->rightchild;  //返回到与最左孩子的父节点,开始遍历其右孩子节点
}
}
//非递归后序遍历
void NicePastOrder(BtNode *ptr)
{
if(ptr == NULL) return ;
Stack st; // BtNode *;
Init_Stack(&st);
BtNode *tag = NULL;

while(ptr != NULL || !empty(&st))
{
while(ptr != NULL)
{
push(&st,ptr);
ptr = ptr->leftchild;
}
ptr = top(&st); pop(&st);    //先出最左孩子结点
if(ptr->rightchild == NULL || ptr->rightchild == tag)
//若右孩子被遍历过,则打印该父节点
{
printf("%c ",ptr->data);
tag = ptr;          //tag标志着某个父节点的右孩子是否被遍历
ptr = NULL;  //重新生成新的未遍历节点
}
else
{
push(&st,ptr);
ptr = ptr->rightchild;
}
}
}


二叉树的遍历主要考虑,左子树,根节点,右子树三者之间的联系,并且保证他们出栈的顺序及规律。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: