加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – Tree :: Simple :: traverse()不访问树的根 – 错误或功

发布时间:2020-12-15 22:05:54 所属栏目:大数据 来源:网络整理
导读:如果我尝试以下代码 #!/usr/bin/env perluse Tree::Simple;# Tree:# a# _________ | ________# / | # b c d # / # e f # # g#my $tree = Tree::Simple-new('a',Tree::Simple-ROOT);$tree-addChildren( Tree::Simple-new('b'),Tree::Simple-new('c'),Tree
如果我尝试以下代码
#!/usr/bin/env perl

use Tree::Simple;

# Tree:
#                   a
#         _________ | ________
#        /          |          
#       b           c          d 
#                 /    
#                e      f  
#                        
#                         g
#

my $tree = Tree::Simple->new('a',Tree::Simple->ROOT);

$tree->addChildren( Tree::Simple->new('b'),Tree::Simple->new('c'),Tree::Simple->new('d'),);

$tree->getChild(1)->addChildren (
                    Tree::Simple->new('e'),Tree::Simple->new('f'),);

$tree->getChild(1)->getChild(1)->addChildren (
                    Tree::Simple->new('g'),);

$trav_func= sub {
    my $node = shift;
    printf "node : %s  leaf : %3s   root : %sn",$node->getNodeValue,$node->isLeaf ? 'yes' : 'no',$node->isRoot ? 'yes' : 'no';
};


# traversal does not report the root - error ?
print "------ preorder : traverse( $trav_func ) n";
$tree->traverse( $trav_func );
print "n";

print "------ postorder : traverse( sub{},$trav_func ) n";
$tree->traverse( sub{},$trav_func );
print "n";

输出是

------ preorder : traverse( $trav_func ) 
node : b  leaf : yes   root : no
node : c  leaf :  no   root : no
node : e  leaf : yes   root : no
node : f  leaf :  no   root : no
node : g  leaf : yes   root : no
node : d  leaf : yes   root : no

------ postorder : traverse( sub{},$trav_func ) 
node : b  leaf : yes   root : no
node : e  leaf : yes   root : no
node : g  leaf : yes   root : no
node : f  leaf :  no   root : no
node : c  leaf :  no   root : no
node : d  leaf : yes   root : no

显示未访问root“a”.我对树遍历的理解是应该访问所有节点.我错了还是在某些情况下有理由不访问root?

附录:

Tree :: Simple :: traverse()实现为:

sub traverse {
    my ($self,$func,$post) = @_;
    # ... some checks here not shown

    foreach my $child ($self->getAllChildren()) { 
        $func->($child);
        $child->traverse($func,$post);
        defined($post) && $post->($child);
    }
  }

对于第一个节点(root),没有调用$func / $post,因此没有访问它.

如果使用覆盖traverse()

package My::Tree::Simple;

use parent 'Tree::Simple';

# the original code of Tree::Simple::traverse() 
# but $func() and $post() outside of foreach-loop
# allowing the root to be visited 

sub my_traverse {
    my ($self,$post) = @_;
    (defined($func)) || die "Insufficient Arguments : Cannot traverse without traversal function";
    (ref($func) eq "CODE") || die "Incorrect Object Type : traversal function is not a function";
    (ref($post) eq "CODE") || die "Incorrect Object Type : post traversal function is not a function"
        if defined($post);

    $func->($self); # put outside of foreach

    foreach my $child ($self->getAllChildren()) {
        $child->my_traverse($func,$post);
    }

    defined($post) && $post->($self); # put outside of foreach
}

它像我预期的那样工作.

解决方法

我最近一直在使用Tree :: Simple包,我认为观察到的行为与文档一致.例如,考虑’getDepth’函数.在文档中它说:

getDepth
Returns a number representing the invocant’s depth within the
hierarchy of Tree::Simple objects.

NOTE: A ROOT tree has the depth of -1. This be because Tree::Simple
assumes that a tree’s root will usually not contain data,but just be
an anchor for the data-containing branches. This may not be intuitive
in all cases,so I mention it here.

从这一点来看,在我看来,你需要并且“锚定”不得包含数据.换句话说,您的树应该如下所示:

# Tree:
#                 anchor
#                   | 
#                   a
#         _________ | ________
#        /          |          
#       b           c          d 
#                 /    
#                e      f  
#                        
#                         g
#

然后,’anchor’将是深度-1,’a’将是深度0,’b’,’c’,’d’将是深度1.

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读