二叉树的遍历——先序遍历、中序遍历、后序遍历

二叉树的遍历是指通过一定顺序访问二叉树的所有结点。遍历方法一般有四种:先序遍历、中序遍历、后序遍历及层次遍历,其中,前三种一般使用深度优先搜索(DFS)实现。

无论是这三种遍历中的哪一种,左子树一定先于右子树遍历,且所谓的“先中后”都是指根结点root在遍历中的位置,因此先序遍历的访问顺序是根结点→左子树→右子树,中序遍历的访问顺序是左子树→根结点→右子树,后序遍历的访问顺序是左子树→右子树→根结点。

 

1.先序遍历

对先序遍历来说,总是先访问根结点root,然后才去访问左子树和右子树,因此先序遍历的遍历顺序是根结点→左子树→右子树,为了实现递归的先序遍历,需要得到两样东西递归式递归边界。其中递归式已经可以由先序遍历的定义直接得到,即先访问根结点(可以做任何事情),再递归访问左子树,最后递归访问右子树。那么这样一直递归访问左子树和右子树,递归边界是什么呢?二叉树的递归定义中的递归边界是二叉树为一棵空树,这一点同样可以用在这里,即在递归访问子树时,如果碰到子树为空,那么就说明到达死胡同。

 

代码如下:

void preorder(node* root){
	if(root==NULL){
		return;	//到达空树,递归边界 
	}
	//访问根结点root,例如将其数据域输出
	printf("%d\n",root->data);
	//访问左子树
	preorder(root->lchild);
	//访问右子树
	preorder(root->rchild);
}

性质:

由于先序遍历先访问根结点,因此对一棵二叉树的先序遍历序列,序列的第一个一定是根结点

 

 

 

2.中序遍历

对中序遍历来说,总是先访问左子树,再访问根结点(即把根结点放在中间访问),最后访问右子树,因此中序遍历的遍历顺序是左子树→根结点→右子树。中序遍历的实现思路和先序遍历完全相同,只不过把根结点的访问放到左子树和右子树中间了。

 

代码如下:

void inorder(node* root){
	if(root==NULL){
		return;	//到达空树,递归边界 
	}
	//访问左子树
	inorder(root->lchild);
	//访问根结点root,例如将其数据域输出
	printf("%d\n",root->data);
	//访问右子树
	inorder(root->rchild);
}

 

性质:

由于中序遍历总是把根结点放在左子树和右子树中间,因此只要知道根结点,就可以通讨根结点在中序遍历序列中的位置区分出左子树和右子树

 

 

3.后序遍历

对后序遍历来说,总是先访问左子树,再访问右子树,最后才访问根结点(即把根结点放在最后访问),因此后序遍历的遍历顺序是左子树→右子树→根结点。

 

代码如下:

void postorder(node* root){
	if(root==NULL){
		return;	//到达空树,递归边界 
	}
	//访问左子树
	postorder(root->lchild);
	//访问右子树
	postorder(root->rchild);
        //访问根结点root,例如将其数据域输出
	printf("%d\n",root->data);
}

 

性质:

后序遍历总是把根结点放在最后访问,这和先序遍历恰好相反,因此对后序遍历序列来说,序列的最后一个一定是根结点

 

总的来说,无论是先序遍历序列还是后序遍历序列,都必须知道中序遍历序列才能唯地确定一棵树。这是因为,通过先序遍历序列和后序遍历序列都只能得到根结点,而只有通过中序遍历序列才能利用根结点把左右子树分开,从而递归生成一棵二叉树。当然,这个做法需要保证在所有元素都不相同时才能使用。

 

 

 

下一节:二叉树的遍历——层次遍历

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值