diff --git a/maps/treemap/enumerable.go b/maps/treemap/enumerable.go index 8cea6d0..5f66ffb 100644 --- a/maps/treemap/enumerable.go +++ b/maps/treemap/enumerable.go @@ -4,10 +4,7 @@ package treemap -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) +import "github.com/emirpasic/gods/containers" func assertEnumerableImplementation() { var _ containers.EnumerableWithKey = (*Map)(nil) @@ -24,7 +21,7 @@ func (m *Map) Each(f func(key interface{}, value interface{})) { // Map invokes the given function once for each element and returns a container // containing the values returned by the given function as key/value pairs. func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map { - newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)} + newMap := &Map{tree: m.tree.New()} iterator := m.Iterator() for iterator.Next() { key2, value2 := f(iterator.Key(), iterator.Value()) @@ -35,7 +32,7 @@ func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, int // Select returns a new container containing all elements for which the given function returns a true value. func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map { - newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)} + newMap := &Map{tree: m.tree.New()} iterator := m.Iterator() for iterator.Next() { if f(iterator.Key(), iterator.Value()) { diff --git a/maps/treemap/iterator.go b/maps/treemap/iterator.go index 02b5c75..3de1482 100644 --- a/maps/treemap/iterator.go +++ b/maps/treemap/iterator.go @@ -4,10 +4,7 @@ package treemap -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) +import "github.com/emirpasic/gods/containers" func assertIteratorImplementation() { var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) @@ -15,7 +12,7 @@ func assertIteratorImplementation() { // Iterator holding the iterator's state type Iterator struct { - iterator rbt.Iterator + iterator containers.ReverseIteratorWithKey } // Iterator returns a stateful iterator whose elements are key/value pairs. diff --git a/maps/treemap/treemap.go b/maps/treemap/treemap.go index a1e58ad..bf62197 100644 --- a/maps/treemap/treemap.go +++ b/maps/treemap/treemap.go @@ -14,7 +14,8 @@ package treemap import ( "fmt" "github.com/emirpasic/gods/maps" - rbt "github.com/emirpasic/gods/trees/redblacktree" + rbt "github.com/spewspews/gods/trees/redblacktree" + "github.com/spewspews/gods/trees" "github.com/emirpasic/gods/utils" "strings" ) @@ -25,7 +26,7 @@ func assertMapImplementation() { // Map holds the elements in a red-black tree type Map struct { - tree *rbt.Tree + tree trees.Tree } // NewWith instantiates a tree map with the custom comparator. @@ -43,6 +44,11 @@ func NewWithStringComparator() *Map { return &Map{tree: rbt.NewWithStringComparator()} } +// NewWithTree instantiates a new empty map with given tree +func NewWithTree(tree trees.Tree) *Map { + return &Map{tree: tree} +} + // Put inserts key-value pair into the map. // Key should adhere to the comparator's type assertion, otherwise method panics. func (m *Map) Put(key interface{}, value interface{}) { @@ -90,19 +96,13 @@ func (m *Map) Clear() { // Min returns the minimum key and its value from the tree map. // Returns nil, nil if map is empty. func (m *Map) Min() (key interface{}, value interface{}) { - if node := m.tree.Left(); node != nil { - return node.Key, node.Value - } - return nil, nil + return m.tree.Min() } // Max returns the maximum key and its value from the tree map. // Returns nil, nil if map is empty. func (m *Map) Max() (key interface{}, value interface{}) { - if node := m.tree.Right(); node != nil { - return node.Key, node.Value - } - return nil, nil + return m.tree.Max() } // String returns a string representation of container diff --git a/maps/treemap/treemap_test.go b/maps/treemap/treemap_test.go index 0039601..4aa3e5e 100644 --- a/maps/treemap/treemap_test.go +++ b/maps/treemap/treemap_test.go @@ -7,6 +7,8 @@ package treemap import ( "fmt" "testing" + + "github.com/spewspews/gods/trees/avltree" ) func TestMapPut(t *testing.T) { @@ -51,6 +53,48 @@ func TestMapPut(t *testing.T) { } } +func TestMapAVLPut(t *testing.T) { + m := NewWithTree(avltree.NewWithIntComparator()) + m.Put(5, "e") + m.Put(6, "f") + m.Put(7, "g") + m.Put(3, "c") + m.Put(4, "d") + m.Put(1, "x") + m.Put(2, "b") + m.Put(1, "a") //overwrite + + if actualValue := m.Size(); actualValue != 7 { + t.Errorf("Got %v expected %v", actualValue, 7) + } + if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { + t.Errorf("Got %v expected %v", actualValue, expectedValue) + } + + // key,expectedValue,expectedFound + tests1 := [][]interface{}{ + {1, "a", true}, + {2, "b", true}, + {3, "c", true}, + {4, "d", true}, + {5, "e", true}, + {6, "f", true}, + {7, "g", true}, + {8, nil, false}, + } + + for _, test := range tests1 { + // retrievals + actualValue, actualFound := m.Get(test[0]) + if actualValue != test[1] || actualFound != test[2] { + t.Errorf("Got %v expected %v", actualValue, test[1]) + } + } + +} func TestMapRemove(t *testing.T) { m := NewWithIntComparator() m.Put(5, "e") diff --git a/sets/treeset/treeset.go b/sets/treeset/treeset.go index baa168a..ee56cc5 100644 --- a/sets/treeset/treeset.go +++ b/sets/treeset/treeset.go @@ -46,7 +46,7 @@ func NewWithStringComparator() *Set { } // NewWithTree instantiates a new empty set with given tree -func NewWithTree(tree trees.Tree) (set *Set) { +func NewWithTree(tree trees.Tree) *Set { return &Set{tree: tree} } diff --git a/trees/avltree/avltree.go b/trees/avltree/avltree.go index f446e19..fe9cf40 100644 --- a/trees/avltree/avltree.go +++ b/trees/avltree/avltree.go @@ -386,6 +386,26 @@ func (t *Tree) Right() *Node { return t.bottom(1) } +// Min returns the minimum key value pair of the AVL tree +// or nils if the tree is empty. +func (t *Tree) Min() (interface{}, interface{}) { + n := t.bottom(0) + if n == nil { + return nil, nil + } + return n.Key, n.Value +} + +// Max returns the minimum key value pair of the AVL tree +// or nils if the tree is empty. +func (t *Tree) Max() (interface{}, interface{}) { + n := t.bottom(1) + if n == nil { + return nil, nil + } + return n.Key, n.Value +} + func (t *Tree) bottom(d int) *Node { n := t.Root if n == nil { diff --git a/trees/redblacktree/redblacktree.go b/trees/redblacktree/redblacktree.go index 3c39694..611aeae 100644 --- a/trees/redblacktree/redblacktree.go +++ b/trees/redblacktree/redblacktree.go @@ -203,6 +203,26 @@ func (tree *Tree) Right() *Node { return parent } +// Min returns the minimum key value pair of the AVL tree +// or nils if the tree is empty. +func (t *Tree) Min() (interface{}, interface{}) { + n := t.Left() + if n == nil { + return nil, nil + } + return n.Key, n.Value +} + +// Max returns the minimum key value pair of the AVL tree +// or nils if the tree is empty. +func (t *Tree) Max() (interface{}, interface{}) { + n := t.Right() + if n == nil { + return nil, nil + } + return n.Key, n.Value +} + // Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found. // Second return parameter is true if floor was found, otherwise false. // diff --git a/trees/trees.go b/trees/trees.go index 52b2b94..d79dcee 100644 --- a/trees/trees.go +++ b/trees/trees.go @@ -23,6 +23,8 @@ type Tree interface { Remove(key interface{}) Get(key interface{}) (interface{}, bool) Keys() []interface{} + Min() (interface{}, interface{}) + Max() (interface{}, interface{}) containers.Container // Empty() bool