二叉树欧拉环游遍历及其应用

二叉树欧拉环游遍历及其应用

学过数据结构的童鞋应该都对二叉树的遍历有所了解,如先序、中序、后序和层次遍历。二叉树还有一种遍历方式为欧拉环游遍历

欧拉环游遍历

欧拉环游遍历就是绕着二叉树的“外围”走一圈。如下图所示:

在这里插入图片描述
其中,每个结点被访问了三次“左边访问”(浅蓝色标记)、“下方访问”(绿色标记)、“右边访问”(粉色标记),且叶子结点的三次访问发生在同一时间

让我们来想想欧拉环游遍历和其他几种遍历的关系,当每个结点仅仅在左边被访问时,其遍历是等价于先序遍历的,同样的,当仅仅只在下边和右边被访问时,遍历结果等价于中序遍历和后序遍历。

欧拉环游遍历代码:

//欧拉环游遍历
void EulerTour_Traverse(BTree T)
{
    printf("Now left: %c \n",T->val);//访问左
    if(T->lchild)
        EulerTour_Traverse(T->lchild);
    printf("Now below: %c \n",T->val);//访问下
    if(T->rchild)
        EulerTour_Traverse(T->rchild);
    printf("Now right: %c \n",T->val);//访问右
}

上图二叉树遍历结果:(先序创建二叉树)

在这里插入图片描述

那么欧拉环游遍历可以解决什么问题呢?

后代数量统计

通过欧拉环游遍历可以方便的得到某个结点的后代数量。初始时设置一个计数器,初始值为0。然后在每次访问结点的左方时递增计数器,当访问到目标结点左方时,记录下此时的计数器值c,当访问到目标结点的右方时,计算当前计数器值c’和c的差值,结果即为该结点的后代数量。

代码如下:

//获得结点值为tar的结点的后代数量
void GetOffspring(BTree T,NodeType tar)
{
    count++;//全局变量,初始为0
    if(T->val == tar)
        count_start = count;//访问到目标结点时进行记录
    if(T->lchild)
        GetOffspring(T->lchild,tar);
    if(T->rchild)
        GetOffspring(T->rchild,tar);
    if(T->val == tar)
    {
        offsprings = (count - count_start);//差值即为后代个数
    }
}

结果如下:(求结点C的后代个数)

在这里插入图片描述

打印完整待括号表达式

利用欧拉环游遍历可以打印完整的带括号的表达式。

void PrintExpression(BTree T)
{
    printf("(");
    if(T->lchild)
        PrintExpression(T->lchild);
    printf("%c",T->val);
    if(T->rchild)
        PrintExpression(T->rchild);
    printf(")");
}

对于下图的二叉树,其完整待括号表达式为(((3)-(1))*((2)/(5)))

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42642142/article/details/107292639