9.2二叉树的遍历

9.2二叉树的遍历

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

先来看前3种遍历方法。前面给出过二叉树的递归定义,这种定义方式将在这里很好的和遍历方法融合在一起。把一棵二叉树分为3个部分:根节点、左子树、右子树,且对左子树和右子树同样进行这样的划分,这样对树的遍历就可以分解为对这3个部分的遍历。读者首先要记住一点,无论是这3种遍历的哪一种,左子树一定优先于右子树遍历。且所谓的“先中后”都是指根节点root在遍历中的位置,因此先序遍历的访问顺序是根节点→左子树→右子树,中序遍历的访问顺序是左子树→根节点→右子树,后序遍历的访问顺序是左子树→右子树→根节点。

9.2.1先序遍历

对先序遍历来说,总是先访问根结点root,然后才去访问左子树和右子树,因此先序遍历的便于顺序是根节点→左子树→右子树.

为了实现递归的先序遍历,需要两样东西:递归式和递归边界。其中递归式可以由线序遍历的定义直接得到,即先访问跟系欸但,再递归访问左子树,最后递归访问右子树。那么这样一直递归访问左子树和右子树,递归边界是什么呢?二叉树的递归定义中的递归边界是二叉树为一棵空树,这一点同样可以在这里用,其他递归访问子树时,如果碰到子树为空,那么就说明达到了死胡同,这样就到了递归式和递归边界,由此可以写出先序遍历的代码。

void preorder(node *root)
{
    if (root == NULL)
    {
        return;
    }
    else
    {
        printf("%d",root->data);
        preorder(root->lc);
        preorder(root->rc);
    }
}
2.先序遍历的性质

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

中序遍历和后序遍历由于方法和先序遍历相同不作方法介绍,只讲性质

9.2.2中序遍历


void inorder(node *root)
{
    if (root == NULL)
    {
        return;
    }
    else
    {
        printf("%d",root->lc->data);
        inorder(root);
        inorder(root->rc);
    }
}

2.中序遍历的性质

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

9.2.3后序遍历

void postorder(node *root)
{
    if (root == NULL)
    {
        return;
    }
    else
    {
        printf("%d",root->lc->data);
        postorder(root->rc);
        postorder(root);
    }
}

2.后序遍历的性质

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

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

9.2.4层序遍历

层序遍历是指按层次的顺序从根节点向下逐层进行遍历,且对同一层的结点为从左到右遍历。这个过程和BFS很很相似,因为BFS进行搜索总是以广度为第一关键词,而对应到二叉树中广度又恰好体现在层次上,因此层次遍历就相当于是对二叉树从根节点开始的广度优先搜索,其基本思路如下:

1.将根节点root加入队列q

2.取出队首结点,访问它

3如果该节点有左孩子,将左孩子入队

4.如果该节点有右孩子,将右孩子入队

5.返回2,直到队列为空

void layerorder(node * root)
{
	queue< node*> q;
	q.push(root);
	while(!q.empty())
	{
		node *p = q.front();
		q.pop();
		printf("%d",p->data);
		if(p->lchild != NULL)
		{
			q.push(p->lchild);
		}
		if(p->rchild != NULL)
		{
			q.push(p->rchild);
		}
	}
}

你可能感兴趣的:(C/C++,算法学习笔记)