先序遍历实现
-
方法描述:
若二叉树为空,则空操作:
若二叉树非空,
访问根结点(D)
先序遍历左子树(L)
先序遍历右子树® -
例子:
上图中的二叉树,访问顺序如下图,
如果用二叉链表来表示上图的访问,则有,
在二叉链表中,对各结点的访问也是递归的,所以对于先序遍历的实现也是递归的。 -
先序遍历递归算法描述:
Status PreOrderTraverse(BiTree T)
{
if (T == NULL)
return OK;
else
{
visit(T); //访问根结点,例如,输出根结点 printf("%d\t",T->data);
PreOrderTraverse(T->lchild); //递归遍历左子树
PreOrderTraverse(T->rchild); //递归遍历右子树
}
}
中序遍历实现
-
方法描述:
若二叉树为空,则空操作:
若二叉树非空,
中序遍历左子树(L)
访问根结点(D)
中序遍历右子树® -
例子:
上图中的二叉树,访问顺序如下图,
-
中序遍历递归算法描述:
Status PreOrderTraverse(BiTree T)
{
if (T == NULL)
return OK;
else
{
PreOrderTraverse(T->lchild); //递归遍历左子树
visit(T); //访问根结点,例如,输出根结点 printf("%d\t",T->data);
PreOrderTraverse(T->rchild); //递归遍历右子树
}
}
后序遍历实现
- 方法描述:
若二叉树为空,则空操作:
若二叉树非空,
后序遍历左子树(L)
后序遍历右子树®
访问根结点(D) - 例子:
上图中的二叉树,访问顺序如下图,
- 后序遍历递归算法描述:
Status PreOrderTraverse(BiTree T)
{
if (T == NULL)
return OK;
else
{
PreOrderTraverse(T->lchild); //递归遍历左子树
PreOrderTraverse(T->rchild); //递归遍历右子树
visit(T); //访问根结点,例如,输出根结点 printf("%d\t",T->data);
}
}
遍历算法的分析
如果去掉输出语句,从递归的角度看,三种算法是完全相同的,或说这三种算法的访问路径是相同的,只是访问结点的时机不同。
如上图,从虚线出发点到终点的路径上,每个结点经过3次。
第1次经过时访问=先序遍历
第2次经过时访问=中序遍历
第3次经过时访问=后序遍历
在访问过程中,每个结点都要路过依次,所以时间复杂度为 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)(单支树的情况下,栈占用最大辅助空间)。