二叉树的遍历(递归加迭代)

先定义结点的结构如下:

//二叉树结点
typedef struct BiTNode{
	//数据
	char data;
	//左右孩子指针
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTreePtr;

后序遍历最难,先搞后序遍历。

递归:

//后序遍历
void PostOrder(BiTreePtr T)
{
	if(nullptr != T)
	{
		//访问左子结点
		PostOrder(T->lchild);
		//访问右子结点
		PostOrder(T->rchild);
		//访问根节点
		Visit(T);
	}
}

迭代:

后序遍历要求在遍历完左右子树后,再访问根。需要判断根结点的左右子树是否均遍历过。因为相对于左右子结点来说,根结点总是被访问。所以我们只需要额外再增加一个指针,指向刚刚访问过的结点即可。只要刚刚访问过的结点是当前结点的右结点,或者当前结点的右结点为空,那么就访问当前结点。否则,去访问当前结点的右子结点。

void PostOrder_iteration(BiTreePtr T)  // 后序遍历的非递归    
{    
    std::stack<BiTreePtr> S;    
    BiTreePtr curr = T ;           // 指向当前要检查的节点  
    BiTreePtr previsited = nullptr;    // 指向前一个被访问的节点  
    while(nullptr != curr || !S.empty())  // 栈空时结束    
    {    
        while(nullptr != curr)            // 一直向左走直到为空  
        {    
            S.push(curr);    
            curr = curr->lchild;    
        }    
        curr = S.top();  
        // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点  
        if(nullptr == curr->rchild || curr->rchild == previsited)    
        {    
            cout<<curr->data<<"  ";    
            previsited = curr;    
            S.pop();    
            curr = nullptr;    
        }    
        else  
            curr = curr->rchild;      // 否则访问右孩子  
    }    
} 


中序遍历

递归:

//中序遍历
void InOrder(BiTreePtr T){
	if(nullptr != T !){
		//访问左子结点
		InOrder(T->lchild);
		//访问根节点
		Visit(T);
		//访问右子结点
		InOrder(T->rchild);
	}
}
迭代:

void InOrder_iteration(BiTreePtr T)   // 中序遍历的非递归  
{  
    if(nullptr == T)  
        return ;  
		
    BiTreePtr curr = T;    // 指向当前要检查的节点  
    std::stack<BiTreePtr> s;
	while(nullptr != curr || !s.empty())
	{
		while(nullptr != curr)
		{
			s.push(curr);
			curr = curr->lchild;
		}
		
		curr = s.top();
		s.pop();
		cout<<curr->data<<"  ";
		curr = curr->rchild;
	}
}

前序遍历

递归:

//前序遍历
void PreOrder(BiTNodePtr T)
{  
    if(nullptr == T)  
        return ;  
	
    printf("%c ", T->data); //输出数据  
    PreOrder(T->lchild); //递归调用,前序遍历左子树  
    PreOrder(T->rchild); //递归调用,前序遍历右子树  
} 
迭代:

void PreOrder_iteration(BiTreePtr T)     //先序遍历的非递归    
{  
    if(nullptr != T)    
        return ;    
    
    std::stack<BiTreePtr> s;  
    s.push(T);  
  
    while(!s.empty())  
    {  
        BiTree temp = s.top();  
        std::cout<<temp->data<<" ";  
        s.pop();  
        if(temp->rchild)  
            s.push(temp->rchild);  
        if(temp->lchild)  
            s.push(temp->lchild);  
    }  
}  
方法二,还是迭代:

void PreOrder_iteration(BiTreePtr T)     //先序遍历的非递归 
{
	if(nullptr != T)  
        return;
		
	std::stack<BiTreePtr> s;
	BiTreePtr curr = T;
	while(nullptr != curr || !s.empty())
	{
		while(nullptr != curr)
		{
			std::cout<<curr->data<<"  ";
			s.push(curr);
			curr = curr->lchild;
		}

		curr = s.top();
		s.pop();
		curr = curr->rchild;
	}
}

最后,还有二叉树的层次遍历。对于层次遍历,类似于图的广度优先DFS。这就该用队列来实现了。

这篇博文写的太长了,新开一篇来写层次遍历及相关变形吧。

http://blog.csdn.net/friendbkf/article/details/50316209

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值