遍历是对树的一种最基本的运算,所谓遍历二叉树,就是按一定的规则和顺序走遍二叉树的所有节点,使每一个节点都被访问一次,而且只被访问一次。由于二叉树是非线性结构,因此,树的遍历实质上是将二叉树的各个节点转换成为一个线性序列来表示。
二叉树常用的遍历方式有:前序遍历、中序遍历、后序遍历、层序遍历四种遍历方式,不同的遍历算法,其思想略有不同,我们来看一下这四种遍历方法主要的算法思想:
1、先序遍历二叉树顺序:根节点 –> 左子树 –> 右子树,即先访问根节点,然后是左子树,最后是右子树。
上图中二叉树的前序遍历结果为:0 -> 1 -> 3 -> 4 -> 2 -> 5 -> 6
2、中序遍历二叉树顺序:左子树 –> 根节点 –> 右子树,即先访问左子树,然后是根节点,最后是右子树。
上图中二叉树的中序遍历结果为:3 -> 1 -> 4 -> 0 -> 5 -> 2 -> 6
3、后续遍历二叉树顺序:左子树 –> 右子树 –> 根节点,即先访问左子树,然后是右子树,最后是根节点。
上图中二叉树的后序遍历结果为:3 -> 4 -> 1 -> 5 -> 6 -> 2 -> 0
4、层序遍历二叉树顺序:从上往下,从左往右,一层一层遍历,直到所有节点都遍历完成。
上图中二叉树的层序遍历结果为:0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6
代码示例:
typedef struct _Node
{
int data;
_Node* lchild;
_Node* rchild;
_Node()
{
data = -1;
}
}Node, *pNode;
//前序遍历
void PreOrderParse(Node* node)
{
if (node == NULL)
return;
cout << node->data;
PreOrderParse(node->lchild);
PreOrderParse(node->rchild);
}
//中序遍历
void InOrderParse(Node* node)
{
if (node == NULL)
return;
PreOrderParse(node->lchild);
cout << node->data;
PreOrderParse(node->rchild);
}
//后序遍历
void PastOrderParse(Node* node)
{
if (node == NULL)
return;
PreOrderParse(node->lchild);
PreOrderParse(node->rchild);
cout << node->data;
}
//层序遍历
void SequenceParse(queue<Node*> que)
{
while (!que.empty())
{
// 得到队头元素并且将队头元素出队列
Node* node = que.front();
que.pop();
// 如果当前节点不为空,那么输出该节点,并且将该节点的左右子节点插入队尾
if (node != NULL)
{
cout << node->data << endl;
que.push(node->lchild);
que.push(node->rchild);
}
}
}