## ~telemachus/algorithms

7efe7ef5bf2ecd1d8f8111e31064af0296325e03 — Peter Aronoff 9 months ago
```Add Insert and Walk functions
```
```3 files changed, 211 insertions(+), 4 deletions(-)

M binarysearchtree.go
M binarysearchtree_test.go
A bst_example_test.go
```
`M binarysearchtree.go => binarysearchtree.go +93 -4`
```@@ 2,10 2,10 @@ package algorithms

type Node struct {
parent *Node
-	lChild *Node
-	rChild *Node
-	Count int
-	Value int
+	left   *Node
+	right  *Node
+	count  int
+	value  int
}

type Tree struct {

@@ 13,6 13,8 @@ type Tree struct {
size int
}

+type fn func(int)
+
func NewBST() *Tree {
return &Tree{}
}

@@ 20,3 22,90 @@ func NewBST() *Tree {
func (t *Tree) Size() int {
return t.size
}
+
+func (t *Tree) Insert(v int) {
+	var prevNode *Node
+	currNode := t.root
+
+	// Walk the tree until we find a spot to insert a new node.
+	for currNode != nil {
+		prevNode = currNode
+		switch {
+		case v < currNode.value:
+			currNode = currNode.left
+		case v > currNode.value:
+			currNode = currNode.right
+		default: // Our value is already present, so we can return early.
+			currNode.count++
+			t.size++
+			return
+		}
+	}
+
+	// Create a new node, place it, and increase the size of the tree.
+	newNode := &Node{value: v, parent: prevNode}
+	switch {
+	case prevNode == nil:
+		t.root = newNode
+	case newNode.value < prevNode.value:
+		prevNode.left = newNode
+	default:
+		prevNode.right = newNode
+	}
+	t.size++
+}
+
+func (t *Tree) InOrderWalk(f fn) {
+	if t == nil {
+		return
+	}
+	t.root.left.inOrderWalk(f)
+	f(t.root.value)
+	t.root.right.inOrderWalk(f)
+
+}
+
+func (n *Node) inOrderWalk(f fn) {
+	if n == nil {
+		return
+	}
+	n.left.inOrderWalk(f)
+	f(n.value)
+	n.right.inOrderWalk(f)
+}
+
+func (t *Tree) PreOrderWalk(f fn) {
+	if t == nil {
+		return
+	}
+	f(t.root.value)
+	t.root.left.preOrderWalk(f)
+	t.root.right.preOrderWalk(f)
+}
+
+func (n *Node) preOrderWalk(f fn) {
+	if n == nil {
+		return
+	}
+	f(n.value)
+	n.left.preOrderWalk(f)
+	n.right.preOrderWalk(f)
+}
+
+func (t *Tree) PostOrderWalk(f fn) {
+	if t == nil {
+		return
+	}
+	t.root.left.postOrderWalk(f)
+	t.root.right.postOrderWalk(f)
+	f(t.root.value)
+}
+
+func (n *Node) postOrderWalk(f fn) {
+	if n == nil {
+		return
+	}
+	n.left.postOrderWalk(f)
+	n.right.postOrderWalk(f)
+	f(n.value)
+}

```
`M binarysearchtree_test.go => binarysearchtree_test.go +12 -0`
```@@ 22,3 22,15 @@ func TestNewBST(t *testing.T) {
t.Errorf("expected %s; actual %s", expected, actual)
}
}
+
+func TestTreeInsert(t *testing.T) {
+	tree := algorithms.NewBST()
+
+	tree.Insert(2)
+	tree.Insert(10)
+	tree.Insert(-15)
+
+	if 3 != tree.Size() {
+		t.Errorf("inserted three items; actual tree.Size() is %d", tree.Size())
+	}
+}

```
`A bst_example_test.go => bst_example_test.go +106 -0`
```@@ 0,0 1,106 @@
+package algorithms_test
+
+import (
+	"fmt"
+
+	"git.sr.ht/~telemachus/algorithms"
+)
+
+func ExampleInOrderWalk() {
+	t := algorithms.NewBST()
+	t.Insert(15)
+	t.Insert(6)
+	t.Insert(18)
+	t.Insert(3)
+	t.Insert(2)
+	t.Insert(4)
+	t.Insert(7)
+	t.Insert(13)
+	t.Insert(9)
+	t.Insert(17)
+	t.Insert(20)
+
+	show := func(i int) {
+		fmt.Printf("%d\n", i)
+	}
+
+	t.InOrderWalk(show)
+	// Output:
+	// 2
+	// 3
+	// 4
+	// 6
+	// 7
+	// 9
+	// 13
+	// 15
+	// 17
+	// 18
+	// 20
+}
+
+func ExamplePreOrderWalk() {
+	t := algorithms.NewBST()
+	t.Insert(15)
+	t.Insert(6)
+	t.Insert(18)
+	t.Insert(3)
+	t.Insert(2)
+	t.Insert(4)
+	t.Insert(7)
+	t.Insert(13)
+	t.Insert(9)
+	t.Insert(17)
+	t.Insert(20)
+
+	show := func(i int) {
+		fmt.Printf("%d\n", i)
+	}
+
+	t.PreOrderWalk(show)
+	// Output:
+	// 15
+	// 6
+	// 3
+	// 2
+	// 4
+	// 7
+	// 13
+	// 9
+	// 18
+	// 17
+	// 20
+}
+
+func ExamplePostOrderWalk() {
+	t := algorithms.NewBST()
+	t.Insert(15)
+	t.Insert(6)
+	t.Insert(18)
+	t.Insert(3)
+	t.Insert(2)
+	t.Insert(4)
+	t.Insert(7)
+	t.Insert(13)
+	t.Insert(9)
+	t.Insert(17)
+	t.Insert(20)
+
+	show := func(i int) {
+		fmt.Printf("%d\n", i)
+	}
+
+	t.PostOrderWalk(show)
+	// Output:
+	// 2
+	// 4
+	// 3
+	// 9
+	// 13
+	// 7
+	// 6
+	// 17
+	// 20
+	// 18
+	// 15
+}

```