From 1a555f27cb19e53fb278c8d7266fd108596c0cf5 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Mon, 25 Nov 2024 22:13:22 +0100 Subject: [PATCH 01/12] add helpers Node and Tree --- helper/node.go | 19 +++++++++++++++++++ helper/tree.go | 15 +++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 helper/node.go create mode 100644 helper/tree.go diff --git a/helper/node.go b/helper/node.go new file mode 100644 index 0000000..39266bb --- /dev/null +++ b/helper/node.go @@ -0,0 +1,19 @@ +package helper + +type Node struct { + data int + left *Node + right *Node +} + +func (node *Node) insert(newNode *Node) { + if node.left != nil && newNode.data < node.data { + node.left.insert(newNode) + } else if newNode.data < node.data { + node.left = newNode + } else if node.left != nil && newNode.data > node.data { + node.right.insert(newNode) + } else { + node.right = newNode + } +} diff --git a/helper/tree.go b/helper/tree.go new file mode 100644 index 0000000..3e8593d --- /dev/null +++ b/helper/tree.go @@ -0,0 +1,15 @@ +package helper + +type Tree struct { + root *Node +} + +func (tree *Tree) add(data int) *Tree { + newNode := &Node{data: data, left: nil, right: nil} + if tree.root != nil { + tree.root.insert(newNode) + } else { + tree.root = newNode + } + return tree +} From 96f562a867dbeaafb9a7649f9b70722c7fb8712e Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Mon, 25 Nov 2024 22:31:03 +0100 Subject: [PATCH 02/12] add walk function to node --- helper/node.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/helper/node.go b/helper/node.go index 39266bb..8ff2287 100644 --- a/helper/node.go +++ b/helper/node.go @@ -17,3 +17,14 @@ func (node *Node) insert(newNode *Node) { node.right = newNode } } + +func (node *Node) walk() []int { + result := make([]int, 0) + for node := node.left; node.left != nil; node = node.left { + } + result = append(result, node.data) + if node.right != nil { + result = append(result, node.right.walk()...) + } + return result +} From 052f84f1771282811093a7848ad1397462f81b98 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Mon, 25 Nov 2024 22:31:30 +0100 Subject: [PATCH 03/12] rename add function of Tree for similar naming --- helper/tree.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/tree.go b/helper/tree.go index 3e8593d..6ee470c 100644 --- a/helper/tree.go +++ b/helper/tree.go @@ -4,7 +4,7 @@ type Tree struct { root *Node } -func (tree *Tree) add(data int) *Tree { +func (tree *Tree) insert(data int) *Tree { newNode := &Node{data: data, left: nil, right: nil} if tree.root != nil { tree.root.insert(newNode) From 02d59d53fce132bd87748fae075db80aa7e6438f Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Mon, 25 Nov 2024 22:41:40 +0100 Subject: [PATCH 04/12] export Root and Insert from Tree --- helper/tree.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/helper/tree.go b/helper/tree.go index 6ee470c..be63086 100644 --- a/helper/tree.go +++ b/helper/tree.go @@ -1,15 +1,15 @@ package helper type Tree struct { - root *Node + Root *Node } -func (tree *Tree) insert(data int) *Tree { +func (tree *Tree) Insert(data int) *Tree { newNode := &Node{data: data, left: nil, right: nil} - if tree.root != nil { - tree.root.insert(newNode) + if tree.Root != nil { + tree.Root.insert(newNode) } else { - tree.root = newNode + tree.Root = newNode } return tree } From a7ca9780e5fd132ebc6a42e720e4d032891afcd0 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Mon, 25 Nov 2024 22:41:51 +0100 Subject: [PATCH 05/12] export Walk from Node --- helper/node.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/node.go b/helper/node.go index 8ff2287..4c886bc 100644 --- a/helper/node.go +++ b/helper/node.go @@ -18,13 +18,13 @@ func (node *Node) insert(newNode *Node) { } } -func (node *Node) walk() []int { +func (node *Node) Walk() []int { result := make([]int, 0) for node := node.left; node.left != nil; node = node.left { } result = append(result, node.data) if node.right != nil { - result = append(result, node.right.walk()...) + result = append(result, node.right.Walk()...) } return result } From 4b1e78ffa1a5f94b7fa64c30f736de16214190b6 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 00:07:55 +0100 Subject: [PATCH 06/12] reorganize Node insert function to fix invalid memory address or nil pointer dereference --- helper/node.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/helper/node.go b/helper/node.go index 4c886bc..f0c1474 100644 --- a/helper/node.go +++ b/helper/node.go @@ -7,14 +7,14 @@ type Node struct { } func (node *Node) insert(newNode *Node) { - if node.left != nil && newNode.data < node.data { - node.left.insert(newNode) - } else if newNode.data < node.data { + if node.left == nil { node.left = newNode - } else if node.left != nil && newNode.data > node.data { - node.right.insert(newNode) - } else { + } else if newNode.data < node.data { + node.left.insert(newNode) + } else if node.right == nil { node.right = newNode + } else { + node.right.insert(newNode) } } From cea3527b0f742e94b6e85300f0b94bf86725f667 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 00:33:43 +0100 Subject: [PATCH 07/12] fix Node Walt function --- helper/node.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/helper/node.go b/helper/node.go index f0c1474..0725216 100644 --- a/helper/node.go +++ b/helper/node.go @@ -20,11 +20,17 @@ func (node *Node) insert(newNode *Node) { func (node *Node) Walk() []int { result := make([]int, 0) - for node := node.left; node.left != nil; node = node.left { - } result = append(result, node.data) - if node.right != nil { - result = append(result, node.right.Walk()...) + println(node.data) + if node.left == nil { + if node.right != nil { + result = append(result, node.right.Walk()...) + } + } else { + result = append(node.left.Walk(), result...) + if node.right != nil { + result = append(result, node.right.Walk()...) + } } return result } From 3bca5443045cf768396bb8509b6d9e87a3664097 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 00:34:58 +0100 Subject: [PATCH 08/12] fix condition in Node insert function --- helper/node.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/node.go b/helper/node.go index 0725216..04f89bc 100644 --- a/helper/node.go +++ b/helper/node.go @@ -7,7 +7,7 @@ type Node struct { } func (node *Node) insert(newNode *Node) { - if node.left == nil { + if newNode.data < node.data && node.left == nil { node.left = newNode } else if newNode.data < node.data { node.left.insert(newNode) From e38398cec42b32a36657199484d190657383a5d6 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 00:36:15 +0100 Subject: [PATCH 09/12] implement BinaryTreeSort using Node and Tree --- algorithms/binary_tree.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 algorithms/binary_tree.go diff --git a/algorithms/binary_tree.go b/algorithms/binary_tree.go new file mode 100644 index 0000000..574d1f7 --- /dev/null +++ b/algorithms/binary_tree.go @@ -0,0 +1,15 @@ +package algorithms + +import "github.com/dimitrijjedich/go-algorithms/helper" + +func BinaryTreeSort(arr []int) []int { + n := len(arr) + result := make([]int, n) + tree := helper.Tree{} + + for i := 0; i < len(arr); i++ { + tree.Insert(arr[i]) + } + result = tree.Root.Walk() + return result +} From 9aa3159bc3fdc27dbc472411c7a84ebc459a15ec Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 11:54:41 +0100 Subject: [PATCH 10/12] remove testlog --- helper/node.go | 1 - 1 file changed, 1 deletion(-) diff --git a/helper/node.go b/helper/node.go index 04f89bc..be6adaa 100644 --- a/helper/node.go +++ b/helper/node.go @@ -21,7 +21,6 @@ func (node *Node) insert(newNode *Node) { func (node *Node) Walk() []int { result := make([]int, 0) result = append(result, node.data) - println(node.data) if node.left == nil { if node.right != nil { result = append(result, node.right.Walk()...) From 6ff23c5e4a07616470010ff4aee31ccc67fdab39 Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 11:55:41 +0100 Subject: [PATCH 11/12] add tests for BinaryTreeSort --- algorithms_test/binary_tree_test.go | 33 +++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 algorithms_test/binary_tree_test.go diff --git a/algorithms_test/binary_tree_test.go b/algorithms_test/binary_tree_test.go new file mode 100644 index 0000000..57b2280 --- /dev/null +++ b/algorithms_test/binary_tree_test.go @@ -0,0 +1,33 @@ +package algorithms_test + +import ( + "github.com/dimitrijjedich/go-algorithms/algorithms" + "reflect" + "testing" +) + +func TestBinaryTreeSort(t *testing.T) { + testCases := []struct { + name string + input []int + expected []int + }{ + {"already sorted", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}}, + {"reverse sorted", []int{5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5}}, + {"unsorted array", []int{5, 3, 8, 6, 2}, []int{2, 3, 5, 6, 8}}, + {"non consecutive array", []int{9, 3, 5, 1, 7}, []int{1, 3, 5, 7, 9}}, + {"empty array", []int{}, []int{}}, + {"single element", []int{42}, []int{42}}, + {"duplicates", []int{3, 1, 2, 3, 1}, []int{1, 1, 2, 3, 3}}, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + result := algorithms.BinaryTreeSort(testCase.input) + + if !reflect.DeepEqual(result, testCase.expected) { + t.Errorf("Failed %s: expected %v, got %v", testCase.name, testCase.expected, result) + } + }) + } +} From 1f64a4048be2fbaa229fdd9553d9d59a69b875bc Mon Sep 17 00:00:00 2001 From: dimitrijjedich Date: Tue, 26 Nov 2024 11:55:55 +0100 Subject: [PATCH 12/12] fix error in case of empty array --- algorithms/binary_tree.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/algorithms/binary_tree.go b/algorithms/binary_tree.go index 574d1f7..775f83e 100644 --- a/algorithms/binary_tree.go +++ b/algorithms/binary_tree.go @@ -10,6 +10,8 @@ func BinaryTreeSort(arr []int) []int { for i := 0; i < len(arr); i++ { tree.Insert(arr[i]) } - result = tree.Root.Walk() + if tree.Root != nil { + result = tree.Root.Walk() + } return result }