我正在Rosettacode.org上查看有关树遍历的页面。我正在看Go的实施,我对Go来说还是个新手,这就是为什么我喜欢你的帮助。
在文件的开头,创建一个结构。到目前为止,这是有道理的。但我不明白的是:
type node struct {
value int
left, right *node
}
left, right *node
部分。我知道左,右变量是指向节点的类型指针。但我不明白为什么,首先我不知道你可以包含你正在创建的类型,在本例中是实际结构本身的节点。然后我真的不明白代码为什么不只是说left, right node
。
func (n *node) iterPreorder(visit func(int)) {
if n == nil {
return
}
visit(n.value)
n.left.iterPreorder(visit)
n.right.iterPreorder(visit)
}
接下来我不知道visit
变量的类型func(int)
如何。然后,我也不知道如何在函数iterPreorder
中使用iterPreorder
。
最后我想问一下,这段代码做了什么?
tree := &node{1,
&node{2,
&node{4,
&node{7, nil, nil},
nil},
&node{5, nil, nil}},
&node{3,
&node{6,
&node{8, nil, nil},
&node{9, nil, nil}},
nil}}
答案 0 :(得分:5)
让我们一步一步来。
它使用指针,因为左和/或右可以是nil(根本没有设置),你不能使用指针。此外,如果他们使用left, right node
,您将拥有无限数量的节点,因为该值将始终设置。
visit func(int)
允许您传递func(int)
类型的函数,就像其他语言的回调一样。
n.left.iterPreorder
/ n.right.iterPreorder
,您实际上是在子节点上调用iterPreorder
,而不是从它调用的同一节点。
代码只是创建一个树并分配它的节点。
更好地形象化:
tree := &node{1,
&node{2,
&node{4,
&node{7, nil, nil},
nil},
&node{5, nil, nil}},
&node{3,
&node{6,
&node{8, nil, nil},
&node{9, nil, nil}},
nil}}
与:
相同tree = &node{value: 1}
tree.left = &node{value:2}
tree.left.left = &node{value: 4}
tree.left.left.left = &node{value: 7}
tree.left.right = &node{value: 5}
tree.right = &node{value:3}
tree.right.left = &node{value: 6}
tree.right.left.left = &node{value: 8}
tree.right.left.right = &node{value: 9}
<强>奖金强>:
&
返回指针,例如n := &node{}
,n
是指向节点的指针。查看this关于Go指针的优秀文章。
此外,Effective Go必须阅读,并尝试浏览tour