鱼C论坛

 找回密码
 立即注册
查看: 2840|回复: 10

[已解决]前序遍历代码的理解

[复制链接]
发表于 2018-8-21 10:43:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
左边是 题目, 右边是 代码

leve 结点所在的层数

从A 开始遍历,level=1;
然后 又遍历了A的左孩子  , B, level+1=2;
当又遍历B的左孩子的时候, B没有左孩子,但level 还是加 1 变成了 3是吗???
此时,T 是 结点B的地址, T->rchild,开始遍历右孩子, leve+1 不是变成了 4了嘛。不是不对了嘛   

请问 我哪里想错了 ?? 请指教
最佳答案
2018-8-21 11:49:52
比较完整的分析
level = 1
visit >> A, level 1
A->lchild, level + 1 == 2
    T != NULL
    visit >> B, level 2
    B->lchild
        T == NULL
    B->rchild, level +1 == 3
        T != NULL
        visit >> D, level 3
        D->lchild, level +1 == 4
              T == NULL
        D->rchild, level +1 == 4
              T == NULL
A->rchild, A.level == 1, level + 1 == 2
    T != NULL
    visit >> C, level 2
        C->rchild, level +1 == 3
            T != NULL
            visit >> E, level 3
            E->lchild, level +1 == 4
                  T == NULL
            E->rchild, level +1 == 4
                  T == NULL
AZJN7E1(%MA7G0)UHCHCWMC.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-8-21 11:29:22 | 显示全部楼层
本帖最后由 claws0n 于 2018-8-21 11:32 编辑

姐姐好~ 上次链表的还没解决??第二个的

这道题,只有三层,哪来 level 4?
递归与函数作用域的问题~

void PreOrderTraverse(BiTree T, int level)
{
        if(T)
        {
                visit(T->data, level);     #这个只是打印数据而已
                PreOrderTraverse(T->lchild, level +1);
                PreOrderTraverse(T->rchild, level +1);
        }
}

二叉树:AB D  CE   #
一开始 visit >> A level 1 接 PreOrderTraverse(T->lchild, level +1)
      进入新函数的作用域 visit >> B level 2 接 PreOrderTraverse(T->lchild, level +1)
             T == NULL,退出,回到上一个函数的作用域
      PreOrderTraverse(T->rchild, level +1)  >> D level 3,函数体执行完毕
A 的 rchild 还没有执行 visit >> C level 2

以此类推。用缩进说明递归的层数。因为 level 是局部变量,所以它们的值在每一层是不会互相影响的~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-21 11:49:52 | 显示全部楼层    本楼为最佳答案   
比较完整的分析
level = 1
visit >> A, level 1
A->lchild, level + 1 == 2
    T != NULL
    visit >> B, level 2
    B->lchild
        T == NULL
    B->rchild, level +1 == 3
        T != NULL
        visit >> D, level 3
        D->lchild, level +1 == 4
              T == NULL
        D->rchild, level +1 == 4
              T == NULL
A->rchild, A.level == 1, level + 1 == 2
    T != NULL
    visit >> C, level 2
        C->rchild, level +1 == 3
            T != NULL
            visit >> E, level 3
            E->lchild, level +1 == 4
                  T == NULL
            E->rchild, level +1 == 4
                  T == NULL
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-21 14:11:10 | 显示全部楼层
claws0n 发表于 2018-8-21 11:49
比较完整的分析
level = 1
visit >> A, level 1

  嗯嗯嗯  谢谢你这么详细的为我解答

  A->lchild, level + 1 == 2
      T != NULL
    visit >> B, level 2
    B->lchild
        T == NULL

为什么到了B的地方的时候, 先是判断 第 它的左孩子 是不是空,才决定 level 加不加 一
而之前 都是 直接 加上 1,再判断 T 是不是空的

   
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-21 14:25:25 | 显示全部楼层
仅有的倔强 发表于 2018-8-21 14:11
嗯嗯嗯  谢谢你这么详细的为我解答

  A->lchild, level + 1 == 2


因为是前序遍历,遍历函数的优先次序
void PreOrderTraverse(BiTree T, int level)
{
    if(T)
    {
        visit(T->data, level);     // 打印 A
        PreOrderTraverse(T->lchild, level +1);                //接下来是寻找 A 的左孩子
                //展开
                if(T)
                {
                      visit(T->data, level);     // 打印 B
                      PreOrderTraverse(T->lchild, level +1);                //接下来是寻找左孩子,左孩子为空,跳出函数
                      PreOrderTraverse(T->rchild, level +1);                //接下来是寻找右孩子,找到 D ……两个空孩子
                }                //B结点遍历完毕
        PreOrderTraverse(T->rchild, level +1);                // 寻找 A 的右孩子
    }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-21 14:53:15 | 显示全部楼层
claws0n 发表于 2018-8-21 14:25
因为是前序遍历,遍历函数的优先次序
void PreOrderTraverse(BiTree T, int level)
{

void PreOrderTraverse(BiTree T, int level)      此时level 是1
{
    if(T)
    {
        visit(T->data, level);     // 打印 A  level=1
        PreOrderTraverse(T->lchild, level +1);                //接下来是寻找 A 的左孩子  ,level=2
                //展开
                if(T)
                {
                      visit(T->data, level);     // 打印 B   level=2
                      PreOrderTraverse(T->lchild, level +1);                //寻找B的左孩子, level=3???
                      PreOrderTraverse(T->rchild, level +1);                //接下来是寻找右孩子,找到 D ……两个空孩子
                }                //B结点遍历完毕 \
        PreOrderTraverse(T->rchild, level +1);             \
    }
}



    它每次调用它自己的时候, 都是先将level 加一, 不管 孩子结点是否为空哇, 我看着是,
    然后 才进去 判断 孩子结点 是否为空, 就跳出来了循环, 但是 level 之前是加了1 的 。 它并没有改变
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-21 14:55:14 | 显示全部楼层
claws0n 发表于 2018-8-21 11:29
姐姐好~ 上次链表的还没解决??第二个的

这道题,只有三层,哪来 level 4?

恩  上次的链表  也算解决吧  按照自己理解的 算是想通拉
谢谢你每次的 帮忙解决问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-21 14:56:41 | 显示全部楼层
claws0n 发表于 2018-8-21 11:49
比较完整的分析
level = 1
visit >> A, level 1


在我看来是这样的

A->lchild, level + 1 == 2
      T != NULL
    visit >> B, level 2
    B->lchild,level 3
        T == NULL
B->rchild ,level 4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-21 15:06:30 | 显示全部楼层
claws0n 发表于 2018-8-21 14:25
因为是前序遍历,遍历函数的优先次序
void PreOrderTraverse(BiTree T, int level)
{

void PreOrderTraverse(BiTree T, int level)    level==1
{
    if(T)
    {
        visit(T->data, level);     // 打印 A        level==1
        PreOrderTraverse(T->lchild, level +1);                //接下来是寻找 A 的左孩子  level==2
                //展开
                if(T)
                {
                      visit(T->data, level);     // 打印 B      level==2
                      PreOrderTraverse(T->lchild, level +1);                //接下来是寻找左孩子,level==3
                      PreOrderTraverse(T->rchild, level +1);                //接下来是寻找右孩子,level==4
                }                //B结点遍历完毕
        PreOrderTraverse(T->rchild, level +1);                // 寻找 A 的右孩子
    }
}



我突然觉得我有点乱乱的啦, 明明知道是错的,   是因为我没有搞清楚 level 作用域的关系吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-21 15:09:51 | 显示全部楼层
仅有的倔强 发表于 2018-8-21 14:56

在我看来是这样的


嗯,如果问题解决了,可以回到帖子编辑成已经解决或采纳答案
还好,略懂,没理解很透,姐姐给机会复习

level 是局部变量,每进入函数一次,将采用函数外最后一个被定义的值。而在函数内部的任何操作将不会作用到函数外部的值
level 1
{
    level 2
    {
         level 3
     }
    level 2
}
如果 level 有 static 的修饰,才会是你说的情形
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2018-8-21 15:32:10 | 显示全部楼层
claws0n 发表于 2018-8-21 15:09
嗯,如果问题解决了,可以回到帖子编辑成已经解决或采纳答案
还好,略懂,没理解很透,姐姐给机会复习 ...

嗯嗯呢恩   对 我的问题就是出在了 level 的作用域上, 我或许懂了,谢谢你!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 19:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表