参考值未被更新。

huangapple go评论93阅读模式
英文:

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]

如果你不喜欢双指针(**),另一种选择是返回新的值并在调用者处进行赋值。

参考/可能的重复问题:

https://stackoverflow.com/questions/35421495/can-the-pointer-in-a-struct-pointer-method-be-reassigned-to-another-instance/35426997#35426997

https://stackoverflow.com/questions/61761945/how-to-modify-the-value-of-a-simple-type-through-pointer-receiver-method-in-go/61762145#61762145

https://stackoverflow.com/questions/45288751/what-use-case-does-pointers-to-pointer-eg-int-have/45297016#45297016

英文:

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:

https://stackoverflow.com/questions/35421495/can-the-pointer-in-a-struct-pointer-method-be-reassigned-to-another-instance/35426997#35426997

https://stackoverflow.com/questions/61761945/how-to-modify-the-value-of-a-simple-type-through-pointer-receiver-method-in-go/61762145#61762145

https://stackoverflow.com/questions/45288751/what-use-case-does-pointers-to-pointer-eg-int-have/45297016#45297016

huangapple
  • 本文由 发表于 2022年10月26日 15:57:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/74204425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定