二叉树的递归和非递归遍历(附代码)
二叉树的遍历方法,按遍历顺序可分为先序遍历、中序遍历、后序遍历。
先序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
通过代码实现,有递归和非递归两种方式,递归比较好理解,非递归效率比较高,直接上代码了:
- 递归方式
//先序遍历
void preorder_recursive(BTNode *root)
{
if(root)
{
printf("%d ", root->data);
preorder_recursive(root->left);
preorder_recursive(root->right);
}
}
//中序遍历
void midorder_recursive(BTNode *root)
{
if(root)
{
midorder_recursive(root->left);
printf("%d ", root->data);
midorder_recursive(root->right);
}
}
//后序遍历
void postorder_recursive(BTNode *root)
{
if(root)
{
postorder_recursive(root->left);
postorder_recursive(root->right);
printf("%d ", root->data);
}
}
- 非递归方式,通过循环+栈替代
/**
非递归,先序方式遍历二叉树
*/
void travelBT_non_recursive_preorder(BTNode *root)
{
BTNode *p;
SeqStack *s = initSeqStack();
p=root;
while(p!=NULL)
{
while(p!=NULL)
{
printf("%d\n",p->data);
if(p->right!=NULL)
pushSeqStack(s, p->right);
p=p->left;
}
if(isSeqStackEmpty(s) == 0)
{
p=popSeqStack(s);
}
else
{
p=NULL;
}
}
}
/**
非递归,中序方式遍历二叉树
*/
void travelBT_non_recursive_midorder(BTNode *root)
{
BTNode *p;
SeqStack *s = initSeqStack();
p=root;
while(p!=NULL||isSeqStackEmpty(s)==0)
{
while(p!=NULL)
{
pushSeqStack(s, p);
p=p->left;
}
if(isSeqStackEmpty(s) == 0)
{
p=popSeqStack(s);
printf("%d\n", p->data);
p=p->right;
}
}
}
/**
非递归,后序方式遍历二叉树(需要借助flag字段)
*/
void travelBT_non_recursive_postorder(BTNode *root)
{
BTNode *p;
SeqStack *s = initSeqStack();
p=root;
do
{
while(p!=NULL)
{
pushSeqStack(s, p);
p=p->left;
}
if(isSeqStackEmpty(s) == 0)
p=popSeqStack(s);
while(p &&p->flag==1)
{
printf("%d ",p->data);
if(isSeqStackEmpty(s) == 0)
p=popSeqStack(s);
else p=NULL;
}
if(p)
{
p->flag=1;
pushSeqStack(s,p);
p=p->right;
}
}while(isSeqStackEmpty(s)==0);
}
思想搞懂后上手写代码,发现跑出来死循环。。还是得多写熟悉了才好啊,到了代码才看出来有哪些边界没有检查。