英文:
Reference values not being updated
问题
我是你的中文翻译助手,以下是翻译好的内容:
我是Golang世界的新手,正在尝试在Golang中实现二叉搜索树(BST)。但是在插入/更新指针值时,值没有被更新/插入。例如,在下面的代码中,输出结果是:
3
[]
我的代码:
package main
import "fmt"
var inOrderTrace []int = []int{}
type node struct {
value int
leftChild *node
rightChild *node
}
type tree struct {
root *node
len int
}
func (myTree tree) inOrderTraverse(node *node) {
if node == nil {
return
}
myTree.inOrderTraverse(node.leftChild)
inOrderTrace = append(inOrderTrace, node.value)
myTree.inOrderTraverse(node.rightChild)
}
func (myTree *tree) insertNode(nodeToManipulate *node, toInsert int) {
if nodeToManipulate == nil {
nodeToManipulate = &node{toInsert, nil, nil}
myTree.len++
return
}
if nodeToManipulate.value > toInsert {
myTree.insertNode(nodeToManipulate.leftChild, toInsert)
} else {
myTree.insertNode(nodeToManipulate.rightChild, toInsert)
}
}
func main() {
myTree := &tree{nil, 0}
var elements []int = []int{1, 0, 2}
for _, element := range elements {
myTree.insertNode(myTree.root, element)
}
myTree.inOrderTraverse(myTree.root)
fmt.Println(myTree.len)
fmt.Println(inOrderTrace)
}
我期望打印出插入的值。谢谢。
英文:
I am new to the Golang world & trying to implement a BST in Golang. But while inserting/updating pointers values are not getting updated/inserted. For example in the following code the output is:
3
[]
my code:
package main
import "fmt"
var inOrderTrace []int = []int{}
type node struct {
value int
leftChild *node
rightChild *node
}
type tree struct {
root *node
len int
}
func (myTree tree) inOrderTraverse(node *node) {
if node == nil {
return
}
myTree.inOrderTraverse(node.leftChild)
inOrderTrace = append(inOrderTrace, node.value)
myTree.inOrderTraverse(node.rightChild)
}
func (myTree *tree) insertNode(nodeToManipulate *node, toInsert int) {
if nodeToManipulate == nil {
nodeToManipulate = &node{toInsert, nil, nil}
myTree.len++
return
}
if nodeToManipulate.value > toInsert {
myTree.insertNode(nodeToManipulate.leftChild, toInsert)
} else {
myTree.insertNode(nodeToManipulate.rightChild, toInsert)
}
}
func main() {
myTree := &tree{nil, 0}
var elements []int = []int{1, 0, 2}
for _, element := range elements {
myTree.insertNode(myTree.root, element)
}
myTree.inOrderTraverse(myTree.root)
fmt.Println(myTree.len)
fmt.Println(inOrderTrace)
}
I am expecting the inserted values to be printed.Thanks.
答案1
得分: 2
insertNode()
函数有一个指针类型的参数(nodeToManipulate *node
)。在insertNode()
函数内部:
nodeToManipulate = &node{toInsert, nil, nil}
这一行只是将一个指针赋值给参数,一个局部变量。如果从main()
函数中调用这个方法,并传递myTree.root
,那么myTree.root
将永远不会被修改,就像上面所写的那样,只有函数参数(一个副本,一个局部变量)会被修改。这意味着你的树永远不会被构建,树的根节点永远不会被修改。
要修改某个东西,你必须传递一个指向它的指针,并修改指向的值。
例如:
func (myTree *tree) insertNode(pnodeToManipulate **node, toInsert int) {
if *pnodeToManipulate == nil {
*pnodeToManipulate = &node{toInsert, nil, nil}
myTree.len++
return
}
nodeToManipulate := *pnodeToManipulate
if nodeToManipulate.value > toInsert {
myTree.insertNode(&nodeToManipulate.leftChild, toInsert)
} else {
myTree.insertNode(&nodeToManipulate.rightChild, toInsert)
}
}
func main() {
myTree := &tree{nil, 0}
var elements []int = []int{1, 0, 2}
for _, element := range elements {
myTree.insertNode(&myTree.root, element)
}
myTree.inOrderTraverse(myTree.root)
fmt.Println(myTree.len)
fmt.Println(inOrderTrace)
}
通过这个改变,输出将会是(在Go Playground上尝试一下):
3
[0 1 2]
如果你不喜欢双指针(**
),另一种选择是返回新的值并在调用者处进行赋值。
参考/可能的重复问题:
英文:
insertNode()
has a parameter of pointer type (nodeToManipulate *node
). Inside insertNode()
:
nodeToManipulate = &node{toInsert, nil, nil}
This line will just assign a pointer to the parameter, a local variable. Calling this method from main()
, and passing myTree.root
, the myTree.root
will never be modified, as written above, only the function parameter (which is a copy, a local variable). This means your tree never gets built, the root of tree never gets modified.
To modify something, you have to pass a pointer to it, and modify the pointed value.
For example:
func (myTree *tree) insertNode(pnodeToManipulate **node, toInsert int) {
if *pnodeToManipulate == nil {
*pnodeToManipulate = &node{toInsert, nil, nil}
myTree.len++
return
}
nodeToManipulate := *pnodeToManipulate
if nodeToManipulate.value > toInsert {
myTree.insertNode(&nodeToManipulate.leftChild, toInsert)
} else {
myTree.insertNode(&nodeToManipulate.rightChild, toInsert)
}
}
func main() {
myTree := &tree{nil, 0}
var elements []int = []int{1, 0, 2}
for _, element := range elements {
myTree.insertNode(&myTree.root, element)
}
myTree.inOrderTraverse(myTree.root)
fmt.Println(myTree.len)
fmt.Println(inOrderTrace)
}
With this change output will be (try it on the Go Playground):
3
[0 1 2]
If you don't like double pointers (**
), another option is to return the new value and assign it at the caller.
See related / possible duplicates:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论