二叉树遍历(非递归)

基于栈的递归消除
递归操作隐式地调用系统栈,使时间和空间性能有比较大的损耗。我们可以根据自己的需要调用合适的栈结构,从而提高效率。
以中序遍历为例:
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 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); //出队节点右孩子入队
 }
}

 

 

 

二叉树的遍历:前序,中序,后序,层序--包括递归和非递归实现

后序遍历还没有明白,继续学习^_^,过几天写个huffman编码的例子来玩玩,不多说了,看代码吧,注意:程序申请的空间并没有释放^_^

/* *******************************************************************
    created:    2005/12/30
    created:    30:12:2005   10:39
    filename:     bintree.h
    author:        Liu Qi
    
    purpose:    二叉树的3种遍历方式(包括非递归实现),前序,后序和中序,先访问根节点就是
    前序(部分书籍称为先根遍历,个人觉得该说法更好^_^),类似的,最后访问根节点就是后序
********************************************************************
*/



#ifndef TREE_H
#define  TREE_H


#include 
< stdio.h >
#include 
< malloc.h >
#include 
< stack >
#include 
< queue >
#include 
< assert.h >

using   namespace  std;



typedef 
int  ElemType;

typedef 
struct  treeT
{
    ElemType key;
    
struct  treeT *  left;
    
struct  treeT *  right;
}
treeT,  * pTreeT;




/* ===========================================================================
* Function name:    visit
* Parameter:        root:树根节点指针
* Precondition:        
* Description:        
* Return value:        
* Author:            Liu Qi, //-
===========================================================================
*/

static   void  visit(pTreeT root)
{
    
if  (NULL  !=  root)
    
{
        printf(
"  %d/n " , root -> key);
    }

}




/* ===========================================================================
* Function name:  BT_MakeNode    
* Parameter:      target:元素值    
* Precondition:      None    
* Postcondition:  NULL != pTreeT 
* Description:      构造一个tree节点,置左右指针为空,并且返回指向新节点的指针    
* Return value:      指向新节点的指针    
* Author:            Liu Qi,  [12/30/2005]
===========================================================================
*/

static  pTreeT BT_MakeNode(ElemType target)
{
    pTreeT pNode 
=  (pTreeT) malloc( sizeof (treeT));

    assert( NULL 
!=  pNode ); 

    pNode
-> key    =  target;
    pNode
-> left   =  NULL;
    pNode
-> right  =  NULL;
    
    
return  pNode;
}



/* ===========================================================================
* Function name:    BT_Insert
* Parameter:        target:要插入的元素值, pNode:指向某一个节点的指针
* Precondition:         NULL != ppTree 
* Description:        插入target到pNode的后面
* Return value:        指向新节点的指针
* Author:            Liu Qi,  [12/29/2005]
===========================================================================
*/

pTreeT BT_Insert(ElemType target, pTreeT
*  ppTree)
{
    pTreeT Node;

    assert( NULL 
!=  ppTree ); 

    Node 
=   * ppTree;
    
if  (NULL  ==  Node)
    
{
        
return   * ppTree  =  BT_MakeNode(target);
    }


    
if  (Node -> key  ==  target)     // 不允许出现相同的元素
     {
        
return  NULL;
    }

    
else   if  (Node -> key  >  target)     // 向左
     {
        
return  BT_Insert(target,  & Node -> left);
    }

    
else
    
{
        
return  BT_Insert(target,  & Node -> right);
    }

}





/* ===========================================================================
* Function name:    BT_PreOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        前序遍历
* Return value:        void
* Author:            Liu Qi,  [12/29/2005]
===========================================================================
*/

void  BT_PreOrder(pTreeT root)
{
    
if  (NULL  !=  root)
    
{
        visit(root);
        BT_PreOrder(root
-> left);
        BT_PreOrder(root
-> right);
    }
    
}



/* ===========================================================================
* Function name:    BT_PreOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        Node
* Description:        前序(先根)遍历非递归算法
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================
*/

void  BT_PreOrderNoRec(pTreeT root)
{
    stack
< treeT  *>  s;

    
while  ((NULL  !=  root)  ||   ! s.empty())
    
{
        
if  (NULL  !=  root)
        
{
            visit(root);
            s.push(root);
            root 
=  root -> left;
        }

        
else
        
{
            root 
=  s.top();
            s.pop();
            root 
=  root -> right;
        }

    }

}




/* ===========================================================================
* Function name:    BT_InOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        中序遍历
* Return value:        void
* Author:            Liu Qi,  [12/30/2005]
===========================================================================
*/

void  BT_InOrder(pTreeT root)
{
    
if  (NULL  !=  root)
    
{
        BT_InOrder(root
-> left);
        visit(root);
        BT_InOrder(root
-> right);
    }

}



/* ===========================================================================
* Function name:    BT_InOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        中序遍历,非递归算法
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================
*/

void  BT_InOrderNoRec(pTreeT root)
{
    stack
< treeT  *>  s;
    
while  ((NULL  !=  root)  ||   ! s.empty())
    
{
        
if  (NULL  !=  root)
        
{
            s.push(root);
            root 
=  root -> left;
        }

        
else
        
{
            root 
=  s.top();
            visit(root);
            s.pop();
            root 
=  root -> right;
        }

    }

}




/* ===========================================================================
* Function name:    BT_PostOrder
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        后序遍历
* Return value:        void
* Author:            Liu Qi,  [12/30/2005]
===========================================================================
*/

void  BT_PostOrder(pTreeT root)
{
    
if  (NULL  !=  root)
    
{
        BT_PostOrder(root
-> left);
        BT_PostOrder(root
-> right);
        visit(root);    
    }

}



/* ===========================================================================
* Function name:    BT_PostOrderNoRec
* Parameter:        root:树根节点指针
* Precondition:        None
* Description:        后序遍历,非递归算法
* Return value:        void
* Author:            Liu Qi, //  [1/1/2006]
===========================================================================
*/

void  BT_PostOrderNoRec(pTreeT root)
{
// 学习中,尚未明白
}



/* ===========================================================================
* Function name:    BT_LevelOrder
* Parameter:        root:树根节点指针
* Precondition:        NULL != root
* Description:        层序遍历
* Return value:        void
* Author:            Liu Qi,  [1/1/2006]
===========================================================================
*/

void  BT_LevelOrder(pTreeT root)
{
    queue
< treeT  *>  q;
    treeT 
* treePtr;

    assert( NULL 
!=  root ); 

    q.push(root);

    
while  ( ! q.empty())
    
{
        treePtr 
=  q.front();
        q.pop();
        visit(treePtr);

        
if  (NULL  !=  treePtr -> left)
        
{
            q.push(treePtr
-> left);    
        }

        
if  (NULL  !=  treePtr -> right)
        
{
            q.push(treePtr
-> right);
        }
    
            
    }

}



#endif




测试代码

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< time.h >
#include 
" tree.h "

#define  MAX_CNT 5
#define  BASE  100

int  main( int  argc,  char   * argv[])
{
    
int  i;
    pTreeT root 
=  NULL;
    
    srand( (unsigned)time( NULL ) ); 
    
    
for  (i = 0 ; i < MAX_CNT; i ++ )
    
{
        BT_Insert(rand() 
%  BASE,  & root);
    }


    
// 前序
    printf( " PreOrder:/n " );
    BT_PreOrder(root);
    printf(
" /n " );

    printf(
" PreOrder no recursion:/n " );
    BT_PreOrderNoRec(root);
    printf(
" /n " );
    
    
// 中序
    printf( " InOrder:/n " );
    BT_InOrder(root);
    printf(
" /n " );

    printf(
" InOrder no recursion:/n " );
    BT_InOrderNoRec(root);
    printf(
" /n " );

    
// 后序
    printf( " PostOrder:/n " );
    BT_PostOrder(root);
    printf(
" /n " );

    
// 层序
    printf( " LevelOrder:/n " );
    BT_LevelOrder(root);
    printf(
" /n " );
    
    
return   0 ;
}

如果有兴趣不妨运行一下,看看效果^_^
另外请教怎样让二叉树漂亮的输出,即按照树的形状输出

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值