二叉树的先序遍历-递归和非递归算法

需要实践先序遍历,我们先建立二叉树。这里采用先序序列建立二叉树,不为别的,因为简单。

typedef int ElemType;
typedef struct BiTNode{
	ElemType data;
	struct BiTNode *lchild, *rchild;
}*BiTree, BiTNode;

void CreateBiTreePreOrder(BiTree &T){
	ElemType data;
	cin>>data;
	if(data==-1){
		T=NULL;
	}else{
		T = new BiTNode();//(BiTree)malloc(sizeof(BiTNode));
	}
	if(!T){
		return;
	}else{
		T->data = data;
		CreateBiTreePreOrder(T->lchild);
		CreateBiTreePreOrder(T->rchild);
	}
}

下面是对先序遍历的实现:

① 首先是最简单的先序递归算法

     递归的思想就是将需要重复的步骤分离出来,反复调用,而且下一次的调用需要用到上一次调用的结果。(可以理解为有依赖关系存在)

//递归的先序遍历
void PreOrder(BiTree T){
	if(T){
		cout<<T->data<<" ";
		PreOrder(T->lchild);
		PreOrder(T->rchild);//这里的压栈,只是为了再一次调用上面的函数
	}
}

 ②下面来对递归算法进行非递归实现

 方法一:模拟递归算法的操作过程。

按照先序的思想,可以转化为循环控制。

  • 入栈前,先输出本节点信息;
  • 先左子树一次入栈,直到没有左子树的结点为止;
  • 出栈栈顶元素,然后,找到右子树,继续①②操作,直到栈为空 结点为空。

 在遍历的过程中,进栈、出栈可能会出现栈空的情况,但这时候遍历还没有结束, 故而采用双重判断。

//先序遍历非递归算法
void PreOrder(BiTree bt){
	//需要用到栈,这里简单写作一个数组来用, 最好用链栈,定义好入栈、出栈的操作接口 
	BiTree T = bt;
	BiTree ptr[20]; 
	int top = -1;
	while(T || top!=-1){
		//按照上面的遍历,先输出数据,然后左子树入栈
		while(T){
			cout<<T->data<<" ";
			ptr[++top]=T;
			T=T->lchild; 
		} 
		if(top!=-1){
			T = ptr[top--];
			T = T->rchild;
		} 
	} 
}

方法二:分析先序遍历的特点。

 

充分考虑先序遍历的特点

  • 1入栈。
  • 1出栈(栈顶元素出栈),输出栈顶元素1,并将1的左右孩子节点入栈;其中右孩子4先入栈,然后左孩子2入栈。(因为,对左边孩子的访问先序遍历先于右孩子,后入栈的先访问)。
  • 2出栈(栈顶元素出栈),输出栈顶元素2,并将2的左右孩子节点入栈,同理5先入栈,3后入栈。
  • 3出栈(栈顶元素出栈),输出栈顶元素33为叶子结点,无孩子,本次无入栈。
  • 5出栈(栈顶元素出栈),输出栈顶元素5
  • 4出栈(最后的栈顶元素出栈),此时 栈空,遍历完毕。
void PreOrder(BiTree bt){
	BiTree ptr[20];
	int top = -1;
	BiTree pt = bt;
	ptr[++top] = pt;
	while(top!=-1){
		pt = ptr[top--];//每次栈顶元素出栈
		cout<<pt->data<<" ";//输出
		if(pt->rchild) 
			ptr[++top] = pt->rchild;
		if(pt->lchild) 
			ptr[++top] = pt->lchild; 
	}
}

 -----------------------------------------分割线------------------------------------------------------------

测试截图:

 

作者:无涯明月

发文时间:2018-11-16

  • 72
    点赞
  • 283
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦否

文章对你有用?不妨打赏一毛两毛

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值