由于二叉树是递归定义的,显然, 可以把二叉树遍历操作设计成递归算法。
从二叉树的定义可知,一棵二叉树由三部分组成:根结点,左子树和右子树。若规定D、L、R分别代表“访问根结点”、“遍历根结点的左子树”和“遍历根结点的右子树”,则共有6种组合: LDR、DLR、LRD、RDL、DRL和RLD,由于先遍历左子树和先遍历右子树在算法设计上没有本质区别,因此我们只讨论6种组合的前三种: DLR、LDR和LRD,根据遍历方法对访问根结点处理的位置不同,称这三种遍历方法分别为前序遍历(DLR)、中序遍历(LDR)和后序遍历(LRD)方法
//定义一颗二叉树
typedef char DataType;
typedef struct Node {
DataType data;
struct Node* leftChild;
struct Node* rightChild;
}BiTreeNode;
void visit(DataType item)
{
printf("%c ", item);
}
(1)前序遍历 (DLR) 递归算法
若二叉树为空,则算法结束;否则:
①访问根结点
②前序遍历根结点的左子树
③前序遍历根结点的右子树
对于所示的二叉树,前序遍历访问结点的次序为:ABDGCEF
void PreOrder(BiTreeNode* root, void visit(DataType item)){
//前序遍历二叉树root,访问操作为visit
if (root != NULL)
{
visit(root->data);
PreOrder(root->leftChild, visit);
PreOrder(root->rightChild, visit);
}
}
(2)中序遍历 (LDR) 递归算法
若二叉树为空,则算法结束;否则:
①中序遍历根结点的左子树
②访问根结点
③中序遍历根结点的右子树。
对于所示的二叉树,中序遍历访问结点的次序为:DGBAECF
void InOrder(BiTreeNode* root, void visit(DataType item)) {
//中序遍历二叉树root,访问操作为visit
if (root != NULL)
{
InOrder(root->leftChild, visit);
visit(root->data);
InOrder(root->rightChild, visit);
}
}
(3)后序遍历 (LRD) 递归算法
若二叉树为空,则算法结束; 否则:
①后序遍历根结点的左子树
②后序遍历根结点的右子树
③访问根结点
对于所示的二叉树,后序遍历访问结点的次序为:GDBEFCA
void PostOrder(BiTreeNode* root, void visit(DataType item)) {
//后序遍历二叉树root,访问操作为visit
if (root != NULL)
{
PostOrder(root->leftChild, visit);
PostOrder(root->rightChild, visit);
visit(root->data);
}
}
由于二叉树是递归定义的,显然, 可以把二叉树遍历操作设计成递归算法。
从二叉树的定义可知,一棵二叉树由三部分组成:根结点,左子树和右子树。若规定D、L、R分别代表“访问根结点”、“遍历根结点的左子树”和“遍历根结点的右子树”,则共有6种组合: LDR、DLR、LRD、RDL、DRL和RLD,由于先遍历左子树和先遍历右子树在算法设计上没有本质区别,因此我们只讨论6种组合的前三种: DLR、LDR和LRD,根据遍历方法对访问根结点处理的位置不同,称这三种遍历方法分别为前序遍历(DLR)、中序遍历(LDR)和后序遍历(LRD)方法
若二叉树为空,则算法结束;否则:
①访问根结点
②前序遍历根结点的左子树
③前序遍历根结点的右子树
对于所示的二叉树,前序遍历访问结点的次序为:ABDGCEF
若二叉树为空,则算法结束;否则:
①中序遍历根结点的左子树
②访问根结点
③中序遍历根结点的右子树。
对于所示的二叉树,中序遍历访问结点的次序为:DGBAECF
若二叉树为空,则算法结束; 否则:
①后序遍历根结点的左子树
②后序遍历根结点的右子树
③访问根结点
对于所示的二叉树,后序遍历访问结点的次序为:GDBEFCA



