二叉树遍历总结

二叉树遍历的递归与非递归算法[@more@]

二叉树的遍历可以大致分为递归遍历和层序遍历。
递归遍历依次遍历左子树和右子树,递归遍历时,每个节点会经过三次。按照访问节点时机的的不同,分为先序,中序和后序遍历。

递归遍历

先序遍历:
1.访问根节点
2.先序遍历左子树
3.先序遍历右子树

//二叉树定义 本例代码为类C伪码 不能直接运行
typedef struct BiTree {
DataType Data; //定义数据域
struct BiTree *LChild,*RChild; //定义左右子树的指针
} *BiTree;

//二叉树先序遍历
void PreTraverse(BiTree root) {
if(root!=NULL) {
Visit(root->data); //访问根节点
PreTraverse(root->LChild); //先序遍历左子树
PreTraverse(root->RChild); //先序遍历右子树
)
}

中序遍历:
1.中序遍历左子树
2.访问根节点
3.中序遍历右子树

//二叉树中序遍历
void InTraverse(BiTree root) {
if(root!=NULL) {
InTraverse(root->LChild); //中序遍历左子树
Visit(root->data); //访问根节点
InTraverse(root->RChild); //中序遍历右子树
}
}

后序遍历:
1.后序遍历左子树
2.后序遍历右子树
3.访问根节点

//二叉树后序遍历
void PostTraverse(BiTree root) {
if(root!=NULL) {
PostTraverse(root->LChild); //后序遍历左子树
PostTraverse(root->RChild); //后序遍历右子树
Visit(root->data); //访问根节点
}
}

基于栈的递归消除

递归操作隐式地调用系统栈,使时间和空间性能有比较大的损耗。我们可以根据自己的需要调用合适的栈结构,从而提高效率。
中序遍历:
void InOrderTraverse(BiTree root) {
InitStack(&s); //初始化栈s
p=root;
while( p!=NULL || !IsEmpty(s) ) { //当前访问节点存在或栈不空
if(p!=NULL) { //当前节点存在
Push(&s,p); //把当前节点压入栈顶
p=p->LChild; //继续遍历左子树
}
else { //当前节点不存在,回溯
Pop(&s,&p); //将栈顶赋给p,出栈
Visit(p->data); //访问节点p
p=p->RChild; //转而访问右子树
}
}
}

void PreOrderNoRec(BiTree root)
{

InitStack(&s); //初始化栈s p=root;

while (p!=NULL || !IsEmpty(s) )
{
if (NULL != p)
{ Visit(p->data); //访问节点p

Push(&s,p); //把当前节点压入栈顶
p=p->LChild; //继续遍历左子树

}
else
{ Pop(&s,&p); //将栈顶赋给p,出栈

root = root->right;
}
}
}

void BT_PostOrderNoRec(pTreeT root)
{
stack s;
pTreeT pre=NULL;

while ((NULL != root) || !s.empty())
{
if (NULL != root)
{
s.push(root);
root = root->left;
}
else
{
root = s.top();
if (root->right!=NULL && pre!=root->right){
root=root->right;
}
else{
root=pre=s.top();
visit(root);
s.pop();
root=NULL;
}
}
}
}

二叉树的层序遍历

借助队列结构,先把根节点入队,如果队列不为空,则让队首节点出队,访问该节点并把它的左右孩子分别入队列,然后再出队,再访问,再左右孩子入队,直到队列为空。这样在遍历过程中,是以树的深度为顺序的。
void Traverse(BiTree root) {
if(root!=null)
EnQueue(&q,root); //根节点入队
while(!IsEmpty(q)) {
BiTree temp = DeQueue(&q); //出队
Visite(temp); //访问出队节点
if(temp->LChild)
EnQueue(&q,temp->LChild); //出队节点左孩子入队
if(temp->RChild)
EnQueue(&q,temp->RChild); //出队节点右孩子入队
}
}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/32405/viewspace-1008791/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/32405/viewspace-1008791/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值