-1

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.

icza
  • 389,944
  • 63
  • 907
  • 827
Ratul Das
  • 35
  • 4
  • 2
    To update the value to which a pointer points you need to use pointer indirection. And btw. to be able to do that, the pointer needs to be non-nil, else you crash your program. E.g. given a *non-nil* `p` of type `*node`, you'd need to do `*p = node{...}` to update what `p` points to. So, in case it's not clear, this `nodeToManipulate = &node{toInsert, nil, nil}` is useless, it does not do what you want it to do. – mkopriva Oct 26 '22 at 08:03
  • 2
    Unrelated to your problem but helpful and important: There are no references in Go and a pointer is not a reference. It's worth using the proper language and not trying to use half-invalid concepts (like references) from other languages. The name of the language is Go. – Volker Oct 26 '22 at 08:16

1 Answers1

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:

Can the pointer in a struct pointer method be reassigned to another instance?

How to modify the value of a simple type through pointer receiver method in Go?

What use case does pointers to pointer (eg **int) have?

icza
  • 389,944
  • 63
  • 907
  • 827