如何创建像树一样的数据结构

how to create a data structure like a tree

对于我的项目,我需要构建一个树结构。我正在寻找一种在叶子上种植它的方法。我通过使用列表结构简化了失败的尝试:

my $root = a => (b => (c=> Nil));
my $here := $root;
while $here.value ~~ Pair {
  $here := $here.value;
}
$here = d => Nil;

这是行不通的,因为我当然无法更改 Nil。 无法分配给不可变值 我怎样才能完成这项工作?

谢谢, 西奥·范登赫维尔

我认为您收到的错误消息 "Cannot assign to an immutable value" 是因为该值不是 container。这是我将叶节点设为容器的示例:

my $root = a => (b => (my $ = (c => Nil)));
my $here := $root;
while $here.value ~~ Pair {
  $here := $here.value;
}
$here = d => Nil;

现在,没有错误信息了。

您正在使用 binding,而不是 $here

的分配
my $root = a => (b => (c=> Nil));
my $here = $root;
while $here.value ~~ Pair {
  $here = $here.value;
}
$here = d => Nil;

当你使用绑定时,左边和右边是同一个对象。一旦它们是同一个对象,那么它们就不能改变(如果绑定对象是不可变的,那就是)。它们是不可变的:

my $bound := 3; $bound = 'þorn'; say $bound; 
# OUTPUT: «Cannot assign to an immutable value␤» 
上面的

3 是不可变的,所以你不能给它赋值。在您提供的代码中,您可以通过重新绑定来更改值,直到您到达一个不可变值,即最后一个 Pair,它解释了消息。

只需使用普通赋值即可。如果你想要的是将 $root 的原始值保留在某处,只需这样做并使用 $root 进行树导航

my $root = a => (b => (c=> Nil));
my $here = $root;
while $root.value ~~ Pair {
  $root = $root.value;
}
$here = d => Nil;
say $here;
say $root; 

$here仍将等于原来的根,$root将导航到最后一个分支和叶子。

根据@Elizabeth、@Håkon 和@jjmerelo 的宝贵意见,我创建了一个示例树实现。

my @paths = <<aap-noot-mies aap-noot-hut aap-juf tuin>>;

my %root;
for @paths -> $fn {
  my @path = $fn.split: '-';
  add-to-tree(@path);
}

print_tree(0, %root);

sub add-to-tree(@path) {
  my %tmp := %root;
  for @path -> $step {
    unless %tmp{$step}:exists {
      my %newtmp;
      %tmp{$step} = %newtmp;
    }
    %tmp := %tmp{$step};
  }
}

sub print_tree($ind, %from) {
  my $margin = ' ' x $ind;
  if %from {
    for %from.kv -> $k, $v {
      say "$margin$k:";
      print_tree($ind + 1, %$v);
    }
  } else {
    say "$margin.";
  }
}