Merge pull request #10 from emirpasic/treemap_min_max

Additions to red-black tree and tree map
pull/11/head
Emir Pasic 9 years ago committed by GitHub
commit 888e7f29b1

@ -400,6 +400,10 @@ func main() {
m.Clear() // empty
m.Empty() // true
m.Size() // 0
// Other:
m.Min() // Returns the minimum key and its value from map.
m.Max() // Returns the maximum key and its value from map.
}
```
@ -471,6 +475,12 @@ func main() {
tree.Clear() // empty
tree.Empty() // true
tree.Size() // 0
// Other:
tree.Left() // gets the left-most (min) node
tree.Right() // get the right-most (max) node
tree.Floor(1) // get the floor node
tree.Ceiling(1) // get the ceiling node
}
```

@ -95,64 +95,6 @@ func (tree *RedBlackTreeExtended) getMaxFromNode(node *rbt.Node) (foundNode *rbt
}
}
// Find ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree is smaller than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *RedBlackTreeExtended) Ceiling(key interface{}) (ceiling *rbt.Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
ceiling, found = node, true
node = node.Left
case compare > 0:
node = node.Right
}
}
if found {
return ceiling, true
}
return nil, false
}
// Find 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.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree is larger than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *RedBlackTreeExtended) Floor(key interface{}) (floor *rbt.Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
node = node.Left
case compare > 0:
floor, found = node, true
node = node.Right
}
}
if found {
return floor, true
}
return nil, false
}
func print(tree *RedBlackTreeExtended) {
max, _ := tree.GetMax()
min, _ := tree.GetMin()
@ -190,30 +132,4 @@ func RedBlackTreeExtendedExample() {
// Value for min key: c
// RedBlackTree
// └── 3
// Ceiling and Floor functions
tree = RedBlackTreeExtended{rbt.NewWithIntComparator()}
tree.Put(1, "a")
tree.Put(2, "b")
tree.Put(4, "d")
tree.Put(6, "f")
tree.Put(7, "g")
//index, ceiling, floor
testValues := [][]interface{}{
{0, 1, nil},
{1, 1, 1},
{2, 2, 2},
{3, 4, 2},
{4, 4, 4},
{5, 6, 4},
{6, 6, 6},
{7, 7, 7},
{8, nil, 7},
}
for _, tt := range testValues {
actualCeiling, _ := tree.Ceiling(tt[0])
actualFloor, _ := tree.Floor(tt[0])
fmt.Printf("test key %d, expected (%d, %d), actual (%d, %d)\n", tt[0], tt[1], tt[2], actualCeiling.Key, actualFloor.Key)
}
}

@ -51,13 +51,13 @@ func TestHashMap(t *testing.T) {
}
// test Keys()
if actualValue, expactedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expactedValue) {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Values()
if actualValue, expactedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expactedValue) {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
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
@ -88,13 +88,13 @@ func TestHashMap(t *testing.T) {
m.Remove(5)
// test Keys()
if actualValue, expactedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expactedValue) {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Values()
if actualValue, expactedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expactedValue) {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// Test Size()
if actualValue := m.Size(); actualValue != 4 {
@ -129,13 +129,13 @@ func TestHashMap(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()

@ -104,6 +104,24 @@ func (m *Map) Clear() {
m.tree.Clear()
}
// 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
}
// 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
}
func (m *Map) String() string {
str := "TreeMap\n"
str += m.tree.String()

@ -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 Min()
if key, value := m.Min(); key != 1 || value != "a" {
t.Errorf("Got %v expected %v", key, 1)
}
// test Max()
if key, value := m.Max(); key != 7 || value != "g" {
t.Errorf("Got %v expected %v", key, 7)
}
// 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()
@ -158,6 +168,15 @@ func TestTreeMap(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, true)
}
// test Min()
if key, value := m.Min(); key != nil || value != nil {
t.Errorf("Got %v expected %v", key, nil)
}
// test Max()
if key, value := m.Max(); key != nil || value != nil {
t.Errorf("Got %v expected %v", key, nil)
}
}
func BenchmarkTreeMap(b *testing.B) {

@ -70,8 +70,8 @@ func TestHashSet(t *testing.T) {
set.Remove()
set.Remove(1)
if actualValue, expactedValues := fmt.Sprintf("%d%d", set.Values()...), [2]string{"23", "32"}; actualValue != expactedValues[0] && actualValue != expactedValues[1] {
t.Errorf("Got %v expected %v", actualValue, expactedValues)
if actualValue, expectedValues := fmt.Sprintf("%d%d", set.Values()...), [2]string{"23", "32"}; actualValue != expectedValues[0] && actualValue != expectedValues[1] {
t.Errorf("Got %v expected %v", actualValue, expectedValues)
}
if actualValue := set.Contains(1); actualValue != false {

@ -61,8 +61,8 @@ func TestTreeSet(t *testing.T) {
// repeat 10 time since map in golang has a random iteration order each time and we want to make sure that the set is ordered
for i := 1; i <= 10; i++ {
if actualValue, expactedValue := fmt.Sprintf("%d%d%d", set.Values()...), "123"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%d%d%d", set.Values()...), "123"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}

@ -186,6 +186,86 @@ func (tree *Tree) Values() []interface{} {
return values
}
// Returns the left-most (min) node or nil if tree is empty.
func (tree *Tree) Left() *Node {
var parent *Node
current := tree.Root
for current != nil {
parent = current
current = current.Left
}
return parent
}
// Returns the right-most (max) node or nil if tree is empty.
func (tree *Tree) Right() *Node {
var parent *Node
current := tree.Root
for current != nil {
parent = current
current = current.Right
}
return parent
}
// Find 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.
//
// Floor node is defined as the largest node that is smaller than or equal to the given node.
// A floor node may not be found, either because the tree is empty, or because
// all nodes in the tree is larger than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Floor(key interface{}) (floor *Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
node = node.Left
case compare > 0:
floor, found = node, true
node = node.Right
}
}
if found {
return floor, true
}
return nil, false
}
// Find ceiling node of the input key, return the ceiling node or nil if no ceiling is found.
// Second return parameter is true if ceiling was found, otherwise false.
//
// Ceiling node is defined as the smallest node that is larger than or equal to the given node.
// A ceiling node may not be found, either because the tree is empty, or because
// all nodes in the tree is smaller than the given node.
//
// Key should adhere to the comparator's type assertion, otherwise method panics.
func (tree *Tree) Ceiling(key interface{}) (ceiling *Node, found bool) {
found = false
node := tree.Root
for node != nil {
compare := tree.Comparator(key, node.Key)
switch {
case compare == 0:
return node, true
case compare < 0:
ceiling, found = node, true
node = node.Left
case compare > 0:
node = node.Right
}
}
if found {
return ceiling, true
}
return nil, false
}
// Removes all nodes from the tree.
func (tree *Tree) Clear() {
tree.Root = nil

@ -51,13 +51,45 @@ func TestRedBlackTree(t *testing.T) {
}
// test Keys()
if actualValue, expactedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.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", tree.Values()...), "abcdefg"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Left()
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Left().Key), "1"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left().Value), "a"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Right()
if actualValue, expectedValue := fmt.Sprintf("%d", tree.Right().Key), "7"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right().Value), "g"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Floor()
if node, found := tree.Floor(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Floor(0); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
// test Ceiling()
if node, found := tree.Ceiling(4); node.Key != 4 || !found {
t.Errorf("Got %v expected %v", node.Key, 4)
}
if node, found := tree.Ceiling(8); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
// key,expectedValue,expectedFound
@ -88,13 +120,18 @@ func TestRedBlackTree(t *testing.T) {
tree.Remove(5)
// Test Keys()
if actualValue, expactedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Values()
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Values()
if actualValue, expactedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// Test Size()
@ -130,13 +167,13 @@ func TestRedBlackTree(t *testing.T) {
tree.Remove(2)
// Test Keys()
if actualValue, expactedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// test Values()
if actualValue, expactedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expactedValue {
t.Errorf("Got %v expected %v", actualValue, expactedValue)
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
// Test Size()
@ -158,6 +195,25 @@ func TestRedBlackTree(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, true)
}
// test Left()
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left()), "<nil>"; actualValue != expectedValue {
t.Errorf("Got %s expected %s", actualValue, expectedValue)
}
// test Right()
if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right()), "<nil>"; actualValue != expectedValue {
t.Errorf("Got %s expected %s", actualValue, expectedValue)
}
// test Floor()
if node, found := tree.Floor(1); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
// test Ceiling()
if node, found := tree.Ceiling(1); node != nil || found {
t.Errorf("Got %v expected %v", node, "<nil>")
}
}
func BenchmarkRedBlackTree(b *testing.B) {

Loading…
Cancel
Save