非递归遍历之前序,中序,后序遍历


你的点赞评论就是对博主最大的鼓励
当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~


🍊自我介绍

  Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”“内容共创官” ,现在我来为大家介绍一下有关物联网-嵌入式方面的内容。


🍊非递归遍历之前序遍历

遍历规则根左右,遇根输出

算法思想
创建一个空栈s,将二叉树的根节点赋值给遍历的指针temp,循环判断当指针temp或s不为空的时候。若当前结点非空,则访问该节点输出值,并将该节点压栈(将该节点的地址压栈),继而遍历其左子树;循环执行,直到当前节点为空时,出栈数据并访问其右子树,再重复如上操作,直至遍历节点的指针为空且栈也为空。

代码展示

//前序遍历
void pre_order(bitree_t *root)
{
	if(root == NULL)
		return ;

	linkstack_t *s = create_empty_linkstack();
	bitree_t *temp = root;

	while(temp != NULL || !is_empty_linkstack(s))
	{
		while(temp != NULL)        
		{
			printf("(%d : %c) ",temp->n,temp->data); //根
			push_linkstack(s,temp);
			temp = temp->lchild;
		}

		if(!is_empty_linkstack(s))
		{
			temp = pop_linkstack(s);        
			temp = temp->rchild;
		}
	}

    free(s);
}

🍊非递归遍历之中序遍历

遍历规则左根右,遇根输出

算法思想:
建一个空栈s,将二叉树的根结点赋值给遍历的指针temp,循环判断当指针temp或s不为空的时候。若当前节点非空,先把左孩子入栈,不着急先输出,先把所有左孩子入栈。左孩子入栈结束,取栈顶输出栈顶元素,遍历右孩子,右孩子入栈。中序遍历的过程和先序一样,唯一的不同就是中序遍历在出栈时访问节点数据。
代码展示:

//中序遍历
void in_order(bitree_t *root)
{
    if(root == NULL)
        return ;
    
    linkstack_t *s = create_empty_linkstack();

    bitree_t *temp = root;

    while(temp != NULL || !is_empty_linkstack(s))
    {
        //遍历左孩子
        if(temp != NULL)        
        {
                push_linkstack(s,temp);        
                temp = temp->lchild; //左
        }else{

                temp = pop_linkstack(s);        
				printf("(%d : %c) ",temp->n,temp->data); //根
                temp = temp->rchild; //右
        }
    }
    
    free(s);
    return ;
}


🍊非递归遍历之后序遍历

遍历规则左右根,遇根输出

算法思想

  后序,要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果 P不存在左孩子和右孩子,则可以直接访问它;或者 P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。

代码演示

//后序遍历
void post_order(bitree_t *root)
{
	
	if(root == NULL)
		return ;

	linkstack_t *s = create_empty_linkstack();//创建空栈
	bitree_t *cur = NULL;//当前数据指针
	bitree_t *pre = NULL;

	push_linkstack(s,root);

	while(!is_empty_linkstack(s))
	{
		cur = get_top_data(s);        
		//以下情况,可以直接输出值:
		//1.左右孩子都为空
		//2.左右孩子存在,并且左孩子或右孩子都被访问过来。

		if((cur->lchild == NULL && cur->rchild == NULL) || \
				(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
		{
			printf("(%d : %c) ",cur->n,cur->data); //根
			pop_linkstack(s);
			pre = cur;
		}else{
			if(cur->rchild != NULL)        
			{
				push_linkstack(s,cur->rchild);        
			}

			if(cur->lchild != NULL)        
			{
				push_linkstack(s,cur->lchild);        
			}
		}
	}


	free(s);
	return ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值