~telemachus/algorithms

7efe7ef5bf2ecd1d8f8111e31064af0296325e03 — Peter Aronoff 9 months ago fb19139
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
}