Browse Source

Adding simple recursive abitrary tree structure.

Beoran 8 years ago
parent
commit
81f2344b46
2 changed files with 131 additions and 0 deletions
  1. 81 0
      tree/tree.go
  2. 50 0
      tree/tree_test.go

+ 81 - 0
tree/tree.go

@@ -0,0 +1,81 @@
+// tree project tree.go
+// a relativey simple recursive tree with an arbitrary amount of children on each level.
+package tree
+
+type Node struct {
+	Child  *Node
+	After  *Node
+	Before *Node
+	Parent *Node
+	Data   interface{}
+}
+
+func NewEmpty() *Node {
+	return &Node{}
+}
+
+func New(parent *Node, data interface{}) *Node {
+	node := NewEmpty()
+	node.Parent = parent
+	node.Data = data
+	return node
+}
+
+func (me *Node) LastSibling() *Node {
+	res := me
+	for res != nil && res.After != nil {
+		res = res.After
+	}
+	return res
+}
+
+func (me *Node) InsertSibling(sibling *Node) *Node {
+	after := me.After
+	me.After = sibling
+	sibling.Before = me
+	sibling.After = after
+	sibling.Parent = me.Parent
+	return sibling
+}
+
+func (me *Node) AppendSibling(sibling *Node) *Node {
+	return me.LastSibling().InsertSibling(sibling)
+}
+
+func (me *Node) AppendChild(child *Node) *Node {
+	child.Parent = me
+	if me.Child == nil {
+		me.Child = child
+	} else {
+		me.Child.AppendSibling(child)
+	}
+	return child
+}
+
+func (me *Node) NewSibling(data interface{}) *Node {
+	node := New(me.Parent, data)
+	return me.AppendSibling(node)
+}
+
+func (me *Node) NewChild(data interface{}) *Node {
+	node := New(me, data)
+	return me.AppendChild(node)
+}
+
+func (me *Node) Walk(walker func(me *Node) *Node) *Node {
+	node := me
+	if found := walker(node); found != nil {
+		return found
+	}
+	if me.Child != nil {
+		if found := me.Child.Walk(walker); found != nil {
+			return found
+		}
+	}
+	if me.After != nil {
+		if found := me.After.Walk(walker); found != nil {
+			return found
+		}
+	}
+	return nil
+}

+ 50 - 0
tree/tree_test.go

@@ -0,0 +1,50 @@
+// tree_tes
+package tree
+
+import (
+	_ "strings"
+	"testing"
+)
+
+func TestNode(test *testing.T) {
+	tree := New(nil, "root")
+	s1 := "l1 c1"
+	s2 := "l1 c2"
+	s3 := "l1 c3"
+	s4 := "l2 c1"
+	l1c1 := tree.NewChild(s1)
+	l1c2 := tree.NewChild(s2)
+	l1c3 := tree.NewChild(s3)
+	l2c1 := l1c1.NewChild(s4)
+
+	if l1c1.Data != s1 {
+		test.Error("Data ")
+	}
+
+	if l1c2.Data != s2 {
+		test.Error("Data ")
+	}
+
+	if l1c3.Data != s3 {
+		test.Error("Data ")
+	}
+
+	if l2c1.Data != s4 {
+		test.Error("Data ")
+	}
+
+	n := tree.Walk(func(node *Node) *Node {
+		if node.Data == s4 {
+			return node
+		}
+		return nil
+	})
+
+	if n.Data != s4 {
+		test.Error("Data ")
+	}
+
+	test.Logf("%v", n.Data)
+
+	test.Log("Hi tree!")
+}