在最小堆二叉树中使用递归搜索和返回节点。

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

Searching and Returning a node using recursion in minheap binary tree

问题

所以我正在尝试通过索引在最小堆树中检索一个节点。调用的方式是,我会初始化一个空的MinHeapNode结构,并通过&node传递其值,以便在递归函数调用之间,如果找到匹配项,则返回。然而,似乎即使找到了结果,新分配的空节点也会被另一个具有该节点空版本的递归调用覆盖。我还在适应指针和地址的概念,所以我认为通过传递值的地址可以解决这个问题,因为它会在调用之间调用相同地址上的相同值。但显然这是不正确的。

type MinHeapNode struct {
	Parent *MinHeapNode
	Left   *MinHeapNode
	Right  *MinHeapNode
	Value  int
	Index  int
}

func (MHN *MinHeapNode) Insert(value int) {

	if !MHN.hasLeftChild() {
		MHN.Left = &MinHeapNode{Parent: MHN, Value: value}
		return
	}

	if !MHN.hasRightChild() {
		MHN.Right = &MinHeapNode{Parent: MHN, Value: value}
		return
	}

	if MHN.hasLeftChild(){
		MHN.Left.Insert(value)
		return
	}

	if MHN.hasRightChild(){
		MHN.Right.Insert(value)
		return
	}
}
func (MHN *MinHeapNode) setIndex(count *int){

	index := *count
	*count = *count +1
	MHN.Index = index

	if MHN.hasLeftChild(){
		MHN.Left.setIndex(count)
	}
	
	if MHN.hasRightChild(){
		MHN.Right.setIndex(count)
	}
	
}


func (MHN *MinHeapNode) getIndex(index int, node *MinHeapNode){
	if MHN == nil{
		return
	}

	if MHN.Index == index{
		node = MHN
		return
	}
		MHN.Left.getIndex(index, node)
		MHN.Right.getIndex(index,node)
	}
}

type MinHeapTree struct {
	Root MinHeapNode
	Size int
}

func (MHT *MinHeapTree) getIndex(index int)(*MinHeapNode, error){
	if MHT.Size < index +1 {
		err := fmt.Errorf("index exceeds tree size")
		return nil, err
	} 
	var node MinHeapNode
	MHT.Root.getIndex(index, &node)
	return &node, nil

}
英文:

So I am trying to retrieve a node in a minheap tree by index. The way that it would be called is that I would intiatate a empty MinHeapNode struct and pass by its value via &amp;node so that between recursive function calls, if a match was found it would then return. However it seems that even given a found result the newly assigned empty node would be overwritten by another recursive call that has an empty version of that node. I'm still getting used to the idea of pointers and addresses so I believed that passing the values address would get around this since it would be calling the same value at the same address between calls. But apparently this is something is not correct.

type MinHeapNode struct {
Parent *MinHeapNode
Left   *MinHeapNode
Right  *MinHeapNode
Value  int
Index  int
}
func (MHN *MinHeapNode) Insert(value int) {
if !MHN.hasLeftChild() {
MHN.Left = &amp;MinHeapNode{Parent: MHN, Value: value}
return
}
if !MHN.hasRightChild() {
MHN.Right = &amp;MinHeapNode{Parent: MHN, Value: value}
return
}
if MHN.hasLeftChild(){
MHN.Left.Insert(value)
return
}
if MHN.hasRightChild(){
MHN.Right.Insert(value)
return
}
}
func (MHN *MinHeapNode) setIndex(count *int){
index := *count
*count = *count +1
MHN.Index = index
if MHN.hasLeftChild(){
MHN.Left.setIndex(count)
}
if MHN.hasRightChild(){
MHN.Right.setIndex(count)
}
}
func (MHN *MinHeapNode) getIndex(index int, node *MinHeapNode){
if MHN == nil{
return
}
if MHN.Index == index{
node = MHN
return
}
MHN.Left.getIndex(index, node)
MHN.Right.getIndex(index,node)
}
}
type MinHeapTree struct {
Root MinHeapNode
Size int
}
func (MHT *MinHeapTree) getIndex(index int)(*MinHeapNode, error){
if MHT.Size &lt; index +1 {
err := fmt.Errorf(&quot;index exceeds tree size&quot;)
return nil, err
} 
var node MinHeapNode
MHT.Root.getIndex(index, &amp;node)
return &amp;node, nil
}

答案1

得分: 0

你所面临的问题似乎出现在getIndex函数中的语句node = MHN(但由于你的代码不完整,我无法确认这是否是唯一的问题)。

node = MHN会更新node的值(它是一个参数,所以按值传递,并且其作用域是函数体)。这不会对node在函数开始时指向的MinHeapNode的值产生影响。要纠正这个问题,可以使用*node = *MHN

可以通过一个简单的程序来演示这一点(playground):

type MinHeapNode struct {
	Test string
}

func getIndexBad(node *MinHeapNode) {
	newNode := MinHeapNode{Test: "Blah"}
	node = &newNode
}

func getIndexGood(node *MinHeapNode) {
	newNode := MinHeapNode{Test: "Blah"}
	*node = newNode
}

func main() {
	n := MinHeapNode{}
	fmt.Println(n)
	getIndexBad(&n)
	fmt.Println(n)
	getIndexGood(&n)
	fmt.Println(n)
}

输出结果表明,“bad”函数不会更新传入的node

{}
{}
{Blah}
英文:

The issue you are facing appears to be with the statement node = MHN in getIndex (but as your code is incomplete I cannot confirm if this is the only issue).

node = MHN will update the value of node (a parameter, so passed by value and, its scope is the function body). This has no impact on the value of the MinHeapNode that node pointed to at the start of the function. To correct this use *node = *MHN.

This can be demonstrated with a simple program (playground)

type MinHeapNode struct {
	Test string
}

func getIndexBad(node *MinHeapNode) {
	newNode := MinHeapNode{Test: &quot;Blah&quot;}
	node = &amp;newNode
}

func getIndexGood(node *MinHeapNode) {
	newNode := MinHeapNode{Test: &quot;Blah&quot;}
	*node = newNode
}
func main() {
	n := MinHeapNode{}
	fmt.Println(n)
	getIndexBad(&amp;n)
	fmt.Println(n)
	getIndexGood(&amp;n)
	fmt.Println(n)
}

The output demonstrates that the "bad" function does not update the passed in node:

{}
{}
{Blah}

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

发表评论

匿名网友

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

确定