I want to create a binary tree and initialize the tree use golang.
And the codes like these:
package Tree
import "fmt"
type TreeNode struct {
Left *TreeNode
Right *TreeNode
Value int
}
func InsertNodeToTree(tree *TreeNode, node *TreeNode)(){
if tree == nil {
tree = node
}
if node.Value > tree.Value {
InsertNodeToTree(tree.Right, node)
}
if node.Value < tree.Value {
InsertNodeToTree(tree.Left, node)
}
}
func InitTree(values ...int) (root *TreeNode) {
rootNode := TreeNode{Value: values[0]}
for _, value := range values {
node := TreeNode{Value:value}
InsertNodeToTree(&rootNode, &node)
}
return &rootNode
}
func main() {
treeNode := InitTree(5, 4, 6, 8, 9, 7, 1, 3, 2)
fmt.Println(treeNode)
}
Why the tree's left and right are nil?
I pass the reference of the tree node, why not work?
In C/C++ programming language, you can use TreeNode *&tree.
But in golang programming language, you can not use *&.
tree is just a copy of the pointer, so you can't point the value to another TreeNode.
I modified your program, and it can run successfully now.
Maybe these codes you need:
package Tree
type TreeNode struct {
Left *TreeNode
Right *TreeNode
Value int
}
var DefaultValue int = -1024
func InsertNodeToTree(tree *TreeNode, node *TreeNode)(){
if tree == nil {
return
}
if tree.Value == DefaultValue {
tree.Value = node.Value
return
}
if node.Value > tree.Value {
if tree.Right == nil {
tree.Right = &TreeNode{Value: DefaultValue}
}
InsertNodeToTree(tree.Right, node)
}
if node.Value < tree.Value {
if tree.Left == nil {
tree.Left = &TreeNode{Value: DefaultValue}
}
InsertNodeToTree(tree.Left, node)
}
}
func InitTree(values ...int) (root *TreeNode) {
rootNode := TreeNode{Value: DefaultValue, Right: nil, Left: nil}
for _, value := range values {
node := TreeNode{Value:value}
InsertNodeToTree(&rootNode, &node)
}
return &rootNode
}
tree is only a copy of the pointer. Assigning to the variable is useless. Instead, you need to assign to an already existing node. For example:
https://play.golang.org/p/Agzby-Yinq
func InsertNodeToTree(tree *TreeNode, node *TreeNode) {
if tree == nil {
panic("cannot insert into nil root")
}
if node.Value > tree.Value {
if tree.Right == nil {
tree.Right = node
} else {
InsertNodeToTree(tree.Right, node)
}
}
if node.Value < tree.Value {
if tree.Left == nil {
tree.Left = node
} else {
InsertNodeToTree(tree.Left, node)
}
}
}
Related
I am implementing node deletion in binary search tree. I have implemented a method which look good (at algorithm standpoint). But do not work. After spending hours trying to understand why, I would love to get some help from you.
BST definition
type Node struct {
Data int
Left *Node
Right *Node
}
Helper methods (they have been tested and works)
// New returns a pointer to a mew node (like the new construct in Go)
func New(data int) *Node {
return &Node{Data: data}
}
// Find checks whether some data exist in the bst and returns the corresponding node
func (bst *Node) Find(data int) *Node {
if bst == nil {
return bst
}
if bst.Data == data {
return bst
}
if data < bst.Data {
return bst.Left.Find(data)
}
return bst.Right.Find(data)
}
// Min returns the smallest element in a bst
func (bst *Node) Min() *Node {
if bst == nil {
return nil
}
current := bst
for current.Left != nil {
current = current.Left
}
return current
}
The non working method
// Delete removes a key from the binary tree
func (bst *Node) Delete(data int) *Node {
if bst == nil {
return bst
}
current := bst
toDelete := current.Find(data)
if toDelete == nil {
return current
}
if toDelete.Right == nil && toDelete.Left != nil {
toDelete = toDelete.Left
return current
}
if toDelete.Right != nil && toDelete.Left == nil {
toDelete = toDelete.Right
return current
}
inOrderSuccessor := toDelete.Right.Min()
toDelete = inOrderSuccessor
return current
}
Test
func main() {
root := bst.New(8)
root.Left = bst.New(3)
root.Right = bst.New(10)
root.Left.Left = bst.New(1)
root.Left.Right = bst.New(6)
fmt.Println(root.InOrder())
root = root.Delete(3)
fmt.Println(root.InOrder())
}
output
1->3->6->8->10->
1->3->6->8->10->
There is something wrong in the Delete method but I could not understand why.
This code can be run in the playground here https://go.dev/play/p/oJZMOCp2BXL
I assume that you think that
toDelete = toDelete.Left
overwrites data that is stored where toDelete points to.
But this operation will just assign a new pointer to toDeletevariable. To overwrite data that is stored in memory you need to dereference the pointer:
*toDelete = *toDelete.Left
You can look at this example https://go.dev/play/p/M62hd3lpHXk and see the difference in a simpler case.
Im trying to teach myself data structures & algos and I am trying to figure out the best way to add an index to a binary tree
Im guessing the best way to do this is to modify an in orderTraversal operation but im not exactly sure how I would implement this and chain that on after every insert and delete function.
type BinarySearchNode struct {
Left *BinarySearchNode
Right *BinarySearchNode
Parent *BinarySearchNode
Data int
Index int
}
func (BSN *BinarySearchNode) Insert(value int){
if BSN.Data > value {
if BSN.Left == nil{
BSN.Left = &BinarySearchNode{Data:value, Parent:BSN}
return
}
BSN.Left.Insert(value)
return
}
if BSN.Right == nil{
BSN.Right = &BinarySearchNode{Data:value, Parent: BSN}
return
}
BSN.Right.Insert(value)
}
func (BSN *BinarySearchNode) setIndex(node *BinarySearchNode, count int)(int){
if node == nil{
return count
}
if node.Right == nil && node.Left == nil{
node.Index = count
}
node.setIndex(node.Left, count+1)
node.setIndex(node.Right, count+1)
return count
}
I have a piece of code for the implementation of binary tree in golang. It may help you.
package main
import (
"fmt"
"math"
)
// A single Node in a binary tree
type Node struct {
// Value contained by the node
Value int
// Left subnode of the node
Left *Node
// Right subnode of the node
Right *Node
}
type BinaryTree struct {
Root *Node
}
// inserting the element in the binary tree
func (tree *BinaryTree) Insert(value int) {
if tree.Root == nil {
node := new(Node)
node.Value = value
tree.Root = node
return
}
current := tree.Root
for {
if value < current.Value {
if current.Left == nil {
node := new(Node)
node.Value = value
current.Left = node
return
} else {
current = current.Left
}
} else {
if current.Right == nil {
node := new(Node)
node.Value = value
current.Right = node
return
} else {
current = current.Right
}
}
}
}
// current left right
func (tree *BinaryTree) RecursivePreOrder(root *Node) {
if root == nil {
return
}
fmt.Println(root.Value)
tree.RecursivePreOrder(root.Left)
tree.RecursivePreOrder(root.Right)
}
func (tree *BinaryTree) IterativePreOrder(root *Node) {
stack := []*Node{}
for {
for root != nil {
fmt.Println(root.Value)
stack = append([]*Node{root}, stack...)
root = root.Left
}
if len(stack) == 0 {
break
}
root = stack[0]
stack = stack[1:]
root = root.Right
}
}
func (tree *BinaryTree) RecursiveInOrder(root *Node) {
if root == nil {
return
}
tree.RecursiveInOrder(root.Left)
fmt.Println(root.Value)
tree.RecursiveInOrder(root.Right)
}
func (tree *BinaryTree) IterativeInOrder(root *Node) {
var stack []*Node
for {
for root != nil {
stack = append([]*Node{root}, stack...)
root = root.Left
}
if len(stack) == 0 {
break
}
root = stack[0]
stack = stack[1:]
fmt.Println(root.Value)
root = root.Right
}
}
func (tree *BinaryTree) RecursivePostOrder(root *Node) {
if root == nil {
return
}
tree.RecursivePostOrder(root.Left)
tree.RecursivePostOrder(root.Right)
fmt.Println(root.Value)
}
func (tree *BinaryTree) IterativePostOrder(root *Node) {
stack := []*Node{}
var previous *Node = nil
for {
for root != nil {
stack = append([]*Node{root}, stack...)
root = root.Left
}
for root == nil && len(stack) != 0 {
root = stack[0]
if root.Right == nil || root.Right == previous {
fmt.Println(root.Value)
stack = stack[1:]
previous = root
root = nil
} else {
root = root.Right
}
}
if len(stack) == 0 {
break
}
}
}
func (tree *BinaryTree) LevelOrder(root *Node) {
// a queue for performing level order traversal of breadth first traversal
queue := []*Node{}
if root != nil {
queue = append(queue, root)
}
for len(queue) > 0 {
root = queue[0]
queue = queue[1:]
fmt.Println(root.Value)
if root.Left != nil {
queue = append(queue, root.Left)
}
if root.Right != nil {
queue = append(queue, root.Right)
}
}
}
func (tree *BinaryTree) Size(root *Node) int {
if root == nil {
return 0
}
sum := tree.Size(root.Left) + 1 + tree.Size(root.Right)
return sum
}
func (tree *BinaryTree) ElementAt(root *Node, index int) *Node {
if index > tree.Size(root)-1 {
fmt.Println("Index doesnot exist")
return nil
}
leftSize := tree.Size(root.Left)
if index == leftSize {
return root
} else if index < leftSize {
return tree.ElementAt(root.Left, index)
} else {
return tree.ElementAt(root.Right, index-leftSize-1)
}
}
func (tree *BinaryTree) Height(root *Node) int {
if root == nil {
return -1
}
return int(math.Max(float64(tree.Height(root.Left)), float64(tree.Height(root.Right)))) + 1
}
// starting point of the program
func main() {
tree := new(BinaryTree)
tree.Insert(44)
tree.Insert(55)
tree.Insert(33)
fmt.Println(tree.Height(tree.Root))
}
I have a binary tree and I would like to find its maximum depth using a breadth-first approach.
I think I am having a logical error in where to increment the depth.
// You can edit this code!
// Click here and start typing.
package main
import (
"log"
"math"
)
type Queue []*Node
func (q *Queue) Enqueue(n *Node) {
*q = append(*q, n)
}
func (q *Queue) Dequeue() *Node {
node := (*q)[0]
*q = (*q)[1:]
return node
}
func (q *Queue) IsEmpty() bool {
return len(*q) == 0
}
type Node struct {
value *int
left *Node
right *Node
}
func (node *Node) insert(value int) {
if node.value == nil {
node.value = &value
return
}
if *node.value <= value {
if node.left == nil {
node.left = &Node{}
}
node.left.insert(value)
return
}
if node.right == nil {
node.right = &Node{}
}
node.right.insert(value)
}
// HELP NEEDED here
func (node *Node) NumberOfVisibleNodes() int {
var counter int
if node == nil || node.value == nil {
return counter
}
hashtable := map[int]int{}
levelDepth := 0
nodeQueue := Queue{node}
for !nodeQueue.IsEmpty() {
currentNode := nodeQueue.Dequeue()
_, found := hashtable[levelDepth]
if !found {
hashtable[levelDepth] = *currentNode.value
}
if currentNode.left != nil {
nodeQueue.Enqueue(currentNode.left)
hashtable[levelDepth+1] = *currentNode.left.value
}
if currentNode.right != nil {
nodeQueue.Enqueue(currentNode.right)
hashtable[levelDepth+1] = *currentNode.right.value
}
levelDepth++
}
return len(hashtable)
}
func (node *Node) NumberOfVisibleNodesRecursively() int {
if node == nil || node.value == nil {
return 0
}
leftMaxDepth := node.left.NumberOfVisibleNodesRecursively()
rightMaxDepth := node.right.NumberOfVisibleNodesRecursively()
maxDepth := math.Max(float64(leftMaxDepth), float64(rightMaxDepth))
return 1 + int(maxDepth)
}
func main() {
testCases := []struct {
expect string
arguments []int
expected int
}{
{
"expect to return 0 when nodes are empty",
[]int{},
0,
},
{
"expect to get 2",
[]int{3, 5},
2,
},
{
"expect to get 3",
[]int{3, 5, 2, 6, 4, 1},
3,
},
{
"expect to return 4",
[]int{3, 5, 2, 6, 4, 1, -10},
4,
},
}
for _, testCase := range testCases {
var tree Node
for _, value := range testCase.arguments {
tree.insert(value)
}
gotResult := tree.NumberOfVisibleNodes()
if gotResult != testCase.expected {
log.Fatalf("%s but got: %d wanted: %d ", testCase.expect, gotResult, testCase.expected)
}
}
}
I wonder if it's even possible. I know the best approach is to use a depth-first approach but I am curious to learn if the breadth approach is possible!
Running code is here: https://go.dev/play/p/exiI-QqRWIM
[UPDATE]
One approach that seems to work is using a tuple.
type TupleQueue []Tuple
func (tq *TupleQueue) Enqueue(t Tuple) {
*tq = append(*tq, t)
}
func (tq *TupleQueue) Dequeue() Tuple {
tuple := (*tq)[0]
*tq = (*tq)[1:]
return tuple
}
func (tq *TupleQueue) IsEmpty() bool {
return len(*tq) == 0
}
func (node *Node) NumberOfVisibleNodes() int {
if node == nil || node.value == nil {
return 0
}
var depth int
tupleQueue := TupleQueue{{depth, node}}
for !tupleQueue.IsEmpty() {
tuple := tupleQueue.Dequeue()
if tuple.level != depth {
depth++
}
if tuple.node.left != nil {
tupleQueue.Enqueue(Tuple{depth + 1, tuple.node.left})
}
if tuple.node.right != nil {
tupleQueue.Enqueue(Tuple{depth + 1, tuple.node.right})
}
}
return depth + 1
}
I wonder if we can do something similar with hashmaps
You don't need tuple or hashmap to do BFS. Just use queue, I show the code below.
func (node *Node) NumberOfVisibleNodes() int {
if node == nil || node.value == nil {
return 0
}
levelDepth := 0
nodeQueue := Queue{node}
for !nodeQueue.IsEmpty() {
tmpQueue := Queue{}
for !nodeQueue.IsEmpty(){
cNode := nodeQueue.Dequeue()
if cNode.right!= nil{
tmpQueue.Enqueue(cNode.right)
}
if cNode.left!= nil{
tmpQueue.Enqueue(cNode.left)
}
}
nodeQueue = tmpQueue
levelDepth++
}
return levelDepth
}
I am trying to implement a tree in Go.
type BinaryNode struct {
left *BinaryNode
right *BinaryNode
data int
}
type BinaryTree struct {
root *BinaryNode
}
Now to insert elements , I have an insert func,
func (t *BinaryNode) insertNode(d int) {
fmt.Printf("%+v\n", t)
if t == nil {
t = &BinaryNode{
data: d,
left: nil,
right: nil,
}
fmt.Printf("%+v inside insert\n", t)
} else {
if d <= t.data {
t.left.insertNode(d)
} else {
t.right.insertNode(d)
}
}
}
If the pointer is nil, create a new node, if not look for left or right, according to the data.
In my main function , i am trying simple few steps :
func main() {
tree1 := &BinaryTree{
root: nil,
}
tree1.root.insertNode(3)
fmt.Printf("%+v\n", tree1.root)
}
What i expect to see is a tree with root value 3.
but i do not see any. Instead I get:
<nil>
&{left:<nil> right:<nil> data:3} inside insert
<nil>
From what I have understood, if the struct pointer is used for methods, a copy is not made. In that case, the modification should persist.
What have I missed here?
this is i thing a simplest solution you can do, i hope its self explanatory
type Bin struct {
left, right *Bin
value int
}
func New(value int) *Bin {
return &Bin{value: value}
}
func (b *Bin) Insert(value int) {
if value <= b.value {
if b.left == nil {
b.left = New(value)
} else {
b.left.Insert(value)
}
} else {
if b.right == nil {
b.right = New(value)
} else {
b.right.Insert(value)
}
}
}
I'd like some help please on how Go pointer receivers work.
I have a contained example below of a binary search tree which hopefully helps me explain.
package main
import "fmt"
type Node struct {
key int
left, right *Node
}
func NewNode(key int) *Node {
return &Node{key, nil, nil}
}
type BST struct {
root *Node
}
func NewBinarySearchTree() *BST {
return &BST{nil}
}
func (t *BST) Insert(key int) {
if t.root == nil {
t.root = NewNode(key)
return
}
var node = t.root
for {
if key < node.key {
if node.left == nil {
node.left = NewNode(key)
return
} else {
node = node.left
}
} else {
if node.right == nil {
node.right = NewNode(key)
return
} else {
node = node.right
}
}
}
}
func inorder(node *Node) {
if node == nil {
return
}
inorder(node.left)
fmt.Print(node.key, " ")
inorder(node.right)
}
func main() {
tree := NewBinarySearchTree()
tree.Insert(3)
tree.Insert(1)
tree.Insert(2)
tree.Insert(4)
inorder(tree.root) // 1 2 3 4
}
After I wrote this, however, I thought I could simplify my insert function as follows:
func (t *BST) Insert2(key int) {
var node *Node
node = t.root
for node != nil {
if key < node.key {
node = node.left
} else {
node = node.right
}
}
node = NewNode(key)
}
However, doing it this way the tree is never updated.
My thinking was...
on the first insert the root node will be nil.
so the local variable node which references t.root will also be nil
the for loop will therefore be skipped.
node = NewNode(key) will have the same effect as t.root =
NewNode(key)
Where does my Insert2 method go wrong? Is there a way it can be tweaked?
You seem to be confusing the usage of pointers.
When you do node = t.root, you merely makes node point to whatever t.root points to.
Later on, when you do node = NewNode(key), you make node points to a newly created item, which is not what you wanted; you want to make t.root point to that new item instead.
Since you intend to modify variables which are of type *Node (root, left and right), we need a pointer to them, so a variable of type **Node, with one more level of indirection.
You can start by making node point to the address of t.root, node := &t.root, then you proceed to your loop.
You can try something like the following:
func (t *BST) Insert3(key int) {
node := &t.root
for *node != nil {
if key < (*node).key {
node = &(*node).left
} else {
node = &(*node).right
}
}
*node = NewNode(key)
}
Pay attention that we use the indirection operator * to access the referenced data, when checking the address on the loop, and also the key.
In the end of the function, *node = NewNode(key) does what you intended to do originally; you are assigning the newly created item to the root, left or right pointers.
node = NewNode(key)
That line doesn't change the tree. That line changes the local variable node; after this line, node points to a different Node, but the object it used to point to is unaffected. To insert into the tree, you have to assign to t.root, node.left, or node.right.