- add reversible iterators to red-black tree

pull/18/head
Emir Pasic 9 years ago
parent ae143689c6
commit 178bc76d62

@ -43,7 +43,7 @@ import (
func assertInterfaceImplementation() { func assertInterfaceImplementation() {
var _ trees.Tree = (*Tree)(nil) var _ trees.Tree = (*Tree)(nil)
var _ containers.IteratorWithKey = (*Iterator)(nil) var _ containers.ReverseIteratorWithKey = (*Iterator)(nil)
} }
type color bool type color bool
@ -281,37 +281,65 @@ func (tree *Tree) Clear() {
// Iterator holding the iterator's state // Iterator holding the iterator's state
type Iterator struct { type Iterator struct {
tree *Tree tree *Tree
left *Node node *Node
} }
// Iterator returns a stateful iterator whose elements are key/value pairs. // Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() Iterator { func (tree *Tree) Iterator() Iterator {
return Iterator{tree: tree, left: nil} return Iterator{tree: tree, node: nil}
} }
// Next moves the iterator to the next element and returns true if there was a next element in the container. // Next moves the iterator to the next element and returns true if there was a next element in the container.
// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). // If Next() returns true, then next element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator. // Modifies the state of the iterator.
func (iterator *Iterator) Next() bool { func (iterator *Iterator) Next() bool {
if iterator.left == nil { if iterator.node == nil {
iterator.left = iterator.tree.Left() iterator.node = iterator.tree.Left()
return iterator.left != nil return iterator.node != nil
} }
if iterator.left.Right != nil { if iterator.node.Right != nil {
iterator.left = iterator.left.Right iterator.node = iterator.node.Right
for iterator.left.Left != nil { for iterator.node.Left != nil {
iterator.left = iterator.left.Left iterator.node = iterator.node.Left
} }
return true return true
} }
if iterator.left.Parent != nil { if iterator.node.Parent != nil {
key := iterator.left.Key node := iterator.node
for iterator.left.Parent != nil { for iterator.node.Parent != nil {
iterator.left = iterator.left.Parent iterator.node = iterator.node.Parent
if iterator.tree.Comparator(key, iterator.left.Key) <= 0 { if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 {
return true return true
} }
} }
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
}
return false
}
// Prev moves the iterator to the previous element and returns true if there was a previous element in the container.
// If Prev() returns true, then previous element's index and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
if iterator.node == nil {
return false
}
if iterator.node.Left != nil {
iterator.node = iterator.node.Left
for iterator.node.Right != nil {
iterator.node = iterator.node.Right
}
return true
}
if iterator.node.Parent != nil {
node := iterator.node
for iterator.node.Parent != nil {
iterator.node = iterator.node.Parent
if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 {
return true
}
}
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
} }
return false return false
} }
@ -319,13 +347,13 @@ func (iterator *Iterator) Next() bool {
// Value returns the current element's value. // Value returns the current element's value.
// Does not modify the state of the iterator. // Does not modify the state of the iterator.
func (iterator *Iterator) Value() interface{} { func (iterator *Iterator) Value() interface{} {
return iterator.left.Value return iterator.node.Value
} }
// Key returns the current element's key. // Key returns the current element's key.
// Does not modify the state of the iterator. // Does not modify the state of the iterator.
func (iterator *Iterator) Key() interface{} { func (iterator *Iterator) Key() interface{} {
return iterator.left.Key return iterator.node.Key
} }
// String returns a string representation of container // String returns a string representation of container

@ -206,7 +206,23 @@ func TestRedBlackTreeCeilingAndFloor(t *testing.T) {
} }
} }
func TestRedBlackTreeIterator1(t *testing.T) { func TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Next() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
for it.Prev() {
t.Errorf("Shouldn't iterate on empty tree")
}
}
func TestRedBlackTreeIterator1Next(t *testing.T) {
tree := NewWithIntComparator() tree := NewWithIntComparator()
tree.Put(5, "e") tree.Put(5, "e")
tree.Put(6, "f") tree.Put(6, "f")
@ -216,29 +232,76 @@ func TestRedBlackTreeIterator1(t *testing.T) {
tree.Put(1, "x") tree.Put(1, "x")
tree.Put(2, "b") tree.Put(2, "b")
tree.Put(1, "a") //overwrite tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator() it := tree.Iterator()
count := 0 count := 0
for it.Next() { for it.Next() {
count++ count++
index := it.Key() key := it.Key()
switch index { switch key {
case count: case count:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator1Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(5, "e")
tree.Put(6, "f")
tree.Put(7, "g")
tree.Put(3, "c")
tree.Put(4, "d")
tree.Put(1, "x")
tree.Put(2, "b")
tree.Put(1, "a") //overwrite
// │ ┌── 7
// └── 6
// │ ┌── 5
// └── 4
// │ ┌── 3
// └── 2
// └── 1
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
default: default:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
} }
} }
if actualValue, expectedValue := count, 7; actualValue != expectedValue { // one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
} }
} }
func TestRedBlackTreeIterator2(t *testing.T) { func TestRedBlackTreeIterator2Next(t *testing.T) {
tree := NewWithIntComparator() tree := NewWithIntComparator()
tree.Put(3, "c") tree.Put(3, "c")
tree.Put(1, "a") tree.Put(1, "a")
@ -247,50 +310,99 @@ func TestRedBlackTreeIterator2(t *testing.T) {
count := 0 count := 0
for it.Next() { for it.Next() {
count++ count++
index := it.Key() key := it.Key()
switch index { switch key {
case count: case count:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
default: default:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
} }
} }
if actualValue, expectedValue := count, 3; actualValue != expectedValue { if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
} }
} }
func TestRedBlackTreeIterator3(t *testing.T) { func TestRedBlackTreeIterator2Prev(t *testing.T) {
tree := NewWithIntComparator() tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator() it := tree.Iterator()
for it.Next() { for it.Next() {
t.Errorf("Shouldn't iterate on empty stack") }
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
} }
func TestRedBlackTreeIterator3Next(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a") tree.Put(1, "a")
it := tree.Iterator()
it = tree.Iterator()
count := 0 count := 0
for it.Next() { for it.Next() {
count++ count++
index := it.Key() key := it.Key()
switch index { switch key {
case count: case count:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
default: default:
if actualValue, expectedValue := index, count; actualValue != expectedValue { if actualValue, expectedValue := key, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue) t.Errorf("Got %v expected %v", actualValue, expectedValue)
} }
} }
} }
if actualValue, expectedValue := count, 1; actualValue != expectedValue { if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIterator3Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(1, "a")
it := tree.Iterator()
for it.Next() {
}
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := key, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
} }
} }
@ -308,7 +420,20 @@ func TestRedBlackTreeIterator4(t *testing.T) {
tree.Put(22, 8) tree.Put(22, 8)
tree.Put(27, 10) tree.Put(27, 10)
// │ ┌── 27
// │ ┌── 25
// │ │ └── 22
// │ ┌── 17
// │ │ └── 15
// └── 13
// │ ┌── 11
// └── 8
// │ ┌── 6
// └── 1
it := tree.Iterator() it := tree.Iterator()
// Iterator (next)
count := 0 count := 0
for it.Next() { for it.Next() {
count++ count++
@ -324,7 +449,27 @@ func TestRedBlackTreeIterator4(t *testing.T) {
} }
} }
} }
if actualValue, expectedValue := count, 10; actualValue != expectedValue { if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
// Iterator (prev)
for it.Prev() {
count--
value := it.Value()
switch value {
case count:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
default:
if actualValue, expectedValue := value, count; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := count, 1; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
} }
} }

Loading…
Cancel
Save