From 6bfa9f318d6341686712b65c50b76b239fa93de0 Mon Sep 17 00:00:00 2001 From: Vlad Alexandru Ionescu Date: Tue, 19 Apr 2016 21:38:32 +0100 Subject: [PATCH] Add ability to get leftmost (minimum) and rightmost (maximum) keys in treemap. --- maps/treemap/treemap.go | 10 ++++++++ maps/treemap/treemap_test.go | 34 ++++++++++++++++---------- trees/redblacktree/redblacktree.go | 38 ++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/maps/treemap/treemap.go b/maps/treemap/treemap.go index 6386d69..06d6185 100644 --- a/maps/treemap/treemap.go +++ b/maps/treemap/treemap.go @@ -73,6 +73,16 @@ func (m *Map) Get(key interface{}) (value interface{}, found bool) { return m.tree.Get(key) } +// Returns the left-most element in the tree map (minimum). +func (m *Map) Left() (key interface{}) { + return m.tree.Left() +} + +// Returns the right-most element in the tree map (maximum). +func (m *Map) Right() (key interface{}) { + return m.tree.Right() +} + // Remove the element from the map by key. // Key should adhere to the comparator's type assertion, otherwise method panics. func (m *Map) Remove(key interface{}) { diff --git a/maps/treemap/treemap_test.go b/maps/treemap/treemap_test.go index 03fb23c..9bdfd63 100644 --- a/maps/treemap/treemap_test.go +++ b/maps/treemap/treemap_test.go @@ -51,13 +51,23 @@ func TestTreeMap(t *testing.T) { } // test Keys() - if actualValue, expactedValue := fmt.Sprintf("%d%d%d%d%d%d%d", m.Keys()...), "1234567"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", m.Keys()...), "1234567"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // test Values() - if actualValue, expactedValue := fmt.Sprintf("%s%s%s%s%s%s%s", m.Values()...), "abcdefg"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", m.Values()...), "abcdefg"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + + // test Left() + if actualValue, expectedValue := fmt.Sprintf("%d", m.Left()), "1"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + + // test Right() + if actualValue, expectedValue := fmt.Sprintf("%d", m.Right()), "7"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // key,expectedValue,expectedFound @@ -88,13 +98,13 @@ func TestTreeMap(t *testing.T) { m.Remove(5) // Test Keys() - if actualValue, expactedValue := fmt.Sprintf("%d%d%d%d", m.Keys()...), "1234"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", m.Keys()...), "1234"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // test Values() - if actualValue, expactedValue := fmt.Sprintf("%s%s%s%s", m.Values()...), "abcd"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", m.Values()...), "abcd"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // Test Size() @@ -130,13 +140,13 @@ func TestTreeMap(t *testing.T) { m.Remove(2) // Test Keys() - if actualValue, expactedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // test Values() - if actualValue, expactedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expactedValue { - t.Errorf("Got %v expected %v", actualValue, expactedValue) + if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { + t.Errorf("Got %v expected %v", actualValue, expectedValue) } // Test Size() diff --git a/trees/redblacktree/redblacktree.go b/trees/redblacktree/redblacktree.go index 507b8d1..67f83b2 100644 --- a/trees/redblacktree/redblacktree.go +++ b/trees/redblacktree/redblacktree.go @@ -186,6 +186,24 @@ func (tree *Tree) Values() []interface{} { return values } +// Returns the left-most key. +func (tree *Tree) Left() interface{} { + left := tree.leftNode() + if left == nil { + return nil + } + return left.Key +} + +// Returns the right-most key. +func (tree *Tree) Right() interface{} { + right := tree.rightNode() + if right == nil { + return nil + } + return right.Key +} + // Removes all nodes from the tree. func (tree *Tree) Clear() { tree.Root = nil @@ -232,6 +250,26 @@ func (tree *Tree) inOrder() []*Node { return nodes } +func (tree *Tree) leftNode() *Node { + var parent *Node + current := tree.Root + for current != nil { + parent = current + current = current.Left + } + return parent +} + +func (tree *Tree) rightNode() *Node { + var parent *Node + current := tree.Root + for current != nil { + parent = current + current = current.Right + } + return parent +} + func output(node *Node, prefix string, isTail bool, str *string) { if node.Right != nil { newPrefix := prefix