遍历二叉树就是按一定的次序,系统地访问树中的所有结点,使每个结点恰好被访问一次。所谓访问结点,其含义是很广的,可以理解为对结点的增、删、修改等各种运算的抽象。在本节讨论中,假定访问结点即为输出结点数据域值。二叉树的遍历是最重要和最基本的运算,二叉树的许多操作都是以遍历为基础的。
遍历二叉树的过程实际上就是按某种规律把二叉树的结点排成一个线性序列。由于二叉树是非线性结构,它的每个结点都可能有两个分支,也就是说一个结点可能有两个后继,所以,二叉树的遍历比较复杂,按照不同规则遍历得到的结果也就不同。另L、D、R分别表示遍历左子树、访问根节点和遍历右子树,则对二叉树的遍历有六种规律:DLR、LDR、LRD、DRL、RDL、RLD。若规定先左后右,则只有三种方案:DLR、LDR、LRD,按照访问根的先后,分别称之为二叉树的先序(根)遍历,中序(根)遍历和后序(根)遍历。
二叉树的三种遍历方式:
1) 先序遍历:
若二叉树为空,则空操作;否则:
- 访问根结点
- 先序遍历左子树
- 先序遍历右子树
void preorder(BinaryTree binaryTree)
{
if (binaryTree) {
std::cout << binaryTree->data;
preorder(binaryTree->lchild);
preorder(binaryTree->rchild);
}
}
2) 中序遍历:
若二叉树为空,则空操作;否则:
- 中序遍历左子树
- 访问根结点
- 中序遍历右子树
void inorder(BinaryTree binaryTree)
{
if (binaryTree) {
inorder(binaryTree->lchild);
std::cout << binaryTree->data;
inorder(binaryTree->rchild);
}
}
3) 后序遍历:
若二叉树为空,则空操作;否则:
- 后序遍历左子树
- 后序遍历右子树
- 访问根结点
void postorder(BinaryTree binaryTree)
{
if (binaryTree) {
std::cout << binaryTree->data;
postorder(binaryTree->lchild);
postorder(binaryTree->rchild);
}
}