Merge pull request #20 from emirpasic/iterator_reset

Iterator Reset
This commit is contained in:
Emir Pasic 2016-06-27 03:11:31 +02:00 committed by GitHub
commit 9078485d8b
22 changed files with 1123 additions and 53 deletions

View File

@ -649,8 +649,9 @@ All ordered containers have stateful iterators. Typically an iterator is obtaine
#### IteratorWithIndex
A [iterator](#iterator) whose elements are referenced by an index. Typical usage:
An [iterator](#iterator) whose elements are referenced by an index.
Typical usage:
```go
it := list.Iterator()
for it.Next() {
@ -659,44 +660,89 @@ for it.Next() {
}
```
Other usages:
```go
if it.First() {
firstIndex, firstValue := it.Index(), it.Value()
...
}
```
```go
for it.Begin(); it.Next(); {
...
}
```
#### IteratorWithKey
A [iterator](#iterator) whose elements are referenced by a key. Typical usage:
An [iterator](#iterator) whose elements are referenced by a key.
Typical usage:
```go
it := map.Iterator()
it := tree.Iterator()
for it.Next() {
key, value := it.Key(), it.Value()
...
}
```
#### ReverseIteratorWithIndex
A [iterator](#iterator) whose elements are referenced by an index. Typical usage:
Other usages:
```go
if it.First() {
firstKey, firstValue := it.Key(), it.Value()
...
}
```
```go
for it.Begin(); it.Next(); {
...
}
```
#### ReverseIteratorWithIndex
An [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration.
Typical usage of iteration in reverse:
```go
it := list.Iterator()
for it.Next() { /* Move to end */ }
for it.Prev() {
for it.End(); it.Prev(); {
index, value := it.Index(), it.Value()
...
}
```
Other usages:
```go
if it.Last() {
lastIndex, lastValue := it.Index(), it.Value()
...
}
```
#### ReverseIteratorWithKey
A [iterator](#iterator) whose elements are referenced by a key. Typical usage:
An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration.
Typical usage of iteration in reverse:
```go
it := map.Iterator()
for it.Next() { /* Move to end */ }
for it.Prev() {
it := tree.Iterator()
for it.End(); it.Prev(); {
key, value := it.Key(), it.Value()
...
}
```
Other usages:
```go
if it.Last() {
lastKey, lastValue := it.Key(), it.Value()
...
}
```
### Enumerable
Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces.

View File

@ -30,56 +30,102 @@ package containers
type IteratorWithIndex interface {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
Next() bool
// Value returns the current element's value.
// Does not modify the state of the iterator.
Value() interface{}
// Index returns the current element's index.
// Does not modify the state of the iterator.
Index() int
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
Begin()
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
First() bool
}
// IteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
type IteratorWithKey interface {
// 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() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
Next() bool
// Value returns the current element's value.
// Does not modify the state of the iterator.
Value() interface{}
// Key returns the current element's key.
// Does not modify the state of the iterator.
Key() interface{}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
Begin()
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
First() bool
}
// ReverseIteratorWithIndex is stateful iterator for ordered containers whose values can be fetched by an index.
//
// Essentially it is the same as IteratorWithIndex, but provides additional Prev() function to enable traversal in reverse.
// Essentially it is the same as IteratorWithIndex, but provides additional:
//
// Prev() function to enable traversal in reverse
//
// Last() function to move the iterator to the last element.
//
// End() function to move the iterator past the last element (one-past-the-end).
type ReverseIteratorWithIndex interface {
// 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 Index() and Value().
// Modifies the state of the iterator.
Prev() bool
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
End()
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
Last() bool
IteratorWithIndex
// Next() bool
// Value() interface{}
// Index() int
}
// ReverseIteratorWithKey is a stateful iterator for ordered containers whose elements are key value pairs.
//
// Essentially it is the same as IteratorWithKey, but provides additional Prev() function to enable traversal in reverse.
// Essentially it is the same as IteratorWithKey, but provides additional:
//
// Prev() function to enable traversal in reverse
//
// Last() function to move the iterator to the last element.
type ReverseIteratorWithKey interface {
// 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().
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
Prev() bool
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
End()
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
Last() bool
IteratorWithKey
// Next() bool
// Value() interface{}
// Key() interface{}
}

View File

@ -0,0 +1,73 @@
/*
Copyright (c) 2015, Emir Pasic
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package examples
import (
"fmt"
"github.com/emirpasic/gods/sets/treeset"
)
// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex
func IteratorWithIndexExample() {
set := treeset.NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
fmt.Print("\nForward iteration\n")
for it.Next() {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nForward iteration (again)\n")
for it.Begin(); it.Next(); {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nBackward iteration\n")
for it.Prev() {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
}
fmt.Print("\nBackward iteration (again)\n")
for it.End(); it.Prev(); {
index, value := it.Index(), it.Value()
fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a]
}
if it.First() {
fmt.Print("\nFirst index: ", it.Index()) // First index: 0
fmt.Print("\nFirst value: ", it.Value()) // First value: a
}
if it.Last() {
fmt.Print("\nLast index: ", it.Index()) // Last index: 3
fmt.Print("\nLast value: ", it.Value()) // Last value: c
}
}

View File

@ -0,0 +1,75 @@
/*
Copyright (c) 2015, Emir Pasic
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package examples
import (
"fmt"
"github.com/emirpasic/gods/maps/treemap"
)
// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey
func IteratorWithKeyExample() {
m := treemap.NewWithIntComparator()
m.Put(1, "a")
m.Put(2, "b")
m.Put(3, "a")
it := m.Iterator()
fmt.Print("\nForward iteration\n")
for it.Next() {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nForward iteration (again)\n")
for it.Begin(); it.Next(); {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c]
}
fmt.Print("\nBackward iteration\n")
for it.Prev() {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
}
fmt.Print("\nBackward iteration (again)\n")
for it.End(); it.Prev(); {
key, value := it.Key(), it.Value()
fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a]
}
if it.First() {
fmt.Print("\nFirst key: ", it.Key()) // First key: 0
fmt.Print("\nFirst value: ", it.Value()) // First value: a
}
if it.Last() {
fmt.Print("\nLast key: ", it.Key()) // Last key: 3
fmt.Print("\nLast value: ", it.Value()) // Last value: c
}
}

View File

@ -193,6 +193,7 @@ func (list *List) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
@ -223,6 +224,34 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.list.size
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()

View File

@ -379,6 +379,75 @@ func TestListIteratorPrev(t *testing.T) {
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorEnd(t *testing.T) {
list := New()
it := list.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
list.Add("a", "b", "c")
it.End()
if index := it.Index(); index != list.Size() {
t.Errorf("Got %v expected %v", index, list.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorLast(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
}
}
func BenchmarkList(b *testing.B) {
for i := 0; i < b.N; i++ {
list := New()

View File

@ -314,6 +314,7 @@ func (list *List) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
@ -362,6 +363,36 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.element = nil
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.list.size
iterator.element = iterator.list.last
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()

View File

@ -379,6 +379,75 @@ func TestListIteratorPrev(t *testing.T) {
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorEnd(t *testing.T) {
list := New()
it := list.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
list.Add("a", "b", "c")
it.End()
if index := it.Index(); index != list.Size() {
t.Errorf("Got %v expected %v", index, list.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorLast(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c")
}
}
func BenchmarkList(b *testing.B) {
for i := 0; i < b.N; i++ {
list := New()

View File

@ -286,6 +286,7 @@ func (list *List) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.list.size {
@ -315,6 +316,21 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.element = nil
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Each calls the given function once for each element, passing that element's index and value.
func (list *List) Each(f func(index int, value interface{})) {
iterator := list.Iterator()

View File

@ -338,6 +338,35 @@ func TestListIteratorNext(t *testing.T) {
}
}
func TestListIteratorBegin(t *testing.T) {
list := New()
it := list.Iterator()
it.Begin()
list.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestListIteratorFirst(t *testing.T) {
list := New()
it := list.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
list.Add("a", "b", "c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func BenchmarkList(b *testing.B) {
for i := 0; i < b.N; i++ {
list := New()

View File

@ -140,13 +140,14 @@ func (m *Map) Iterator() Iterator {
// 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() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
return iterator.iterator.Next()
}
// 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().
// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Prev() bool {
return iterator.iterator.Prev()
@ -164,6 +165,32 @@ func (iterator *Iterator) Key() interface{} {
return iterator.iterator.Key()
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.iterator.Begin()
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.iterator.End()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
return iterator.iterator.First()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
return iterator.iterator.Last()
}
// Each calls the given function once for each element, passing that element's key and value.
func (m *Map) Each(f func(key interface{}, value interface{})) {
iterator := m.Iterator()

View File

@ -377,7 +377,6 @@ func TestMapIteratorPrev(t *testing.T) {
}
countDown := m.Size()
for it.Prev() {
countDown--
key := it.Key()
value := it.Value()
switch key {
@ -399,13 +398,70 @@ func TestMapIteratorPrev(t *testing.T) {
if actualValue, expectedValue := value, countDown; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
countDown--
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
func TestMapIteratorBegin(t *testing.T) {
m := NewWithIntComparator()
it := m.Iterator()
it.Begin()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
for it.Next() {
}
it.Begin()
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapTreeIteratorEnd(t *testing.T) {
m := NewWithIntComparator()
it := m.Iterator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it.End()
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestMapIteratorFirst(t *testing.T) {
m := NewWithIntComparator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestMapIteratorLast(t *testing.T) {
m := NewWithIntComparator()
m.Put(3, "c")
m.Put(1, "a")
m.Put(2, "b")
it := m.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func BenchmarkMap(b *testing.B) {
for i := 0; i < b.N; i++ {
m := NewWithIntComparator()

View File

@ -120,6 +120,7 @@ func (set *Set) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.tree.Size() {
@ -150,6 +151,36 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
iterator.iterator.Begin()
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.tree.Size()
iterator.iterator.End()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.iterator.Last()
}
// Each calls the given function once for each element, passing that element's index and value.
func (set *Set) Each(f func(index int, value interface{})) {
iterator := set.Iterator()

View File

@ -278,6 +278,69 @@ func TestSetIteratorPrev(t *testing.T) {
}
}
func TestSetIteratorBegin(t *testing.T) {
m := NewWithStringComparator()
it := m.Iterator()
it.Begin()
m.Add("a", "b", "c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestSetIteratorEnd(t *testing.T) {
set := NewWithStringComparator()
it := set.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
set.Add("a", "b", "c")
it.End()
if index := it.Index(); index != set.Size() {
t.Errorf("Got %v expected %v", index, set.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c")
}
}
func TestSetIteratorFirst(t *testing.T) {
set := NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a")
}
}
func TestSetIteratorLast(t *testing.T) {
set := NewWithStringComparator()
set.Add("a", "b", "c")
it := set.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c")
}
}
func BenchmarkSet(b *testing.B) {
for i := 0; i < b.N; i++ {
set := NewWithIntComparator()

View File

@ -111,6 +111,7 @@ func (stack *Stack) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.stack.Size() {
@ -142,6 +143,34 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.stack.Size()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
// String returns a string representation of container
func (stack *Stack) String() string {
str := "ArrayStack\n"

View File

@ -176,6 +176,83 @@ func TestStackIteratorPrev(t *testing.T) {
}
}
func TestStackIteratorBegin(t *testing.T) {
stack := New()
it := stack.Iterator()
it.Begin()
stack.Push("a")
stack.Push("b")
stack.Push("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorEnd(t *testing.T) {
stack := New()
it := stack.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
it.End()
if index := it.Index(); index != stack.Size() {
t.Errorf("Got %v expected %v", index, stack.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != stack.Size()-1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, stack.Size()-1, "a")
}
}
func TestStackIteratorFirst(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorLast(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "a")
}
}
func BenchmarkStack(b *testing.B) {
for i := 0; i < b.N; i++ {
stack := New()

View File

@ -106,6 +106,7 @@ func (stack *Stack) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.stack.Size() {
@ -127,6 +128,20 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// String returns a string representation of container
func (stack *Stack) String() string {
str := "LinkedListStack\n"

View File

@ -136,6 +136,39 @@ func TestStackIterator(t *testing.T) {
}
}
func TestStackIteratorBegin(t *testing.T) {
stack := New()
it := stack.Iterator()
it.Begin()
stack.Push("a")
stack.Push("b")
stack.Push("c")
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func TestStackIteratorFirst(t *testing.T) {
stack := New()
it := stack.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
stack.Push("a")
stack.Push("b")
stack.Push("c")
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c")
}
}
func BenchmarkStack(b *testing.B) {
for i := 0; i < b.N; i++ {
stack := New()

View File

@ -127,6 +127,7 @@ func (heap *Heap) Iterator() Iterator {
// 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 index and value can be retrieved by Index() and Value().
// If Next() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.index < iterator.heap.Size() {
@ -158,6 +159,34 @@ func (iterator *Iterator) Index() int {
return iterator.index
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.index = -1
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.index = iterator.heap.Size()
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's index and value can be retrieved by Index() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
// String returns a string representation of container
func (heap *Heap) String() string {
str := "BinaryHeap\n"

View File

@ -191,6 +191,83 @@ func TestBinaryHeapIteratorPrev(t *testing.T) {
}
}
func TestBinaryHeapIteratorBegin(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
it.Begin()
heap.Push(2)
heap.Push(3)
heap.Push(1)
for it.Next() {
}
it.Begin()
it.Next()
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
}
}
func TestListIteratorEnd(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
if index := it.Index(); index != -1 {
t.Errorf("Got %v expected %v", index, -1)
}
it.End()
if index := it.Index(); index != 0 {
t.Errorf("Got %v expected %v", index, 0)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
it.End()
if index := it.Index(); index != heap.Size() {
t.Errorf("Got %v expected %v", index, heap.Size())
}
it.Prev()
if index, value := it.Index(), it.Value(); index != heap.Size()-1 || value != 2 {
t.Errorf("Got %v,%v expected %v,%v", index, value, heap.Size()-1, 2)
}
}
func TestStackIteratorFirst(t *testing.T) {
heap := NewWithIntComparator()
it := heap.Iterator()
if actualValue, expectedValue := it.First(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
heap.Push(3) // [3]
heap.Push(2) // [2,3]
heap.Push(1) // [1,3,2](2 swapped with 1, hence last)
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 0 || value != 1 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1)
}
}
func TestBinaryHeapIteratorLast(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
tree.Push(2)
tree.Push(3)
tree.Push(1) // [1,3,2](2 swapped with 1, hence last)
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if index, value := it.Index(), it.Value(); index != 2 || value != 2 {
t.Errorf("Got %v,%v expected %v,%v", index, value, 2, 2)
}
}
func BenchmarkBinaryHeap(b *testing.B) {
for i := 0; i < b.N; i++ {
heap := NewWithIntComparator()

View File

@ -282,66 +282,103 @@ func (tree *Tree) Clear() {
type Iterator struct {
tree *Tree
node *Node
position position
}
type position byte
const (
begin, between, end position = 0, 1, 2
)
// Iterator returns a stateful iterator whose elements are key/value pairs.
func (tree *Tree) Iterator() Iterator {
return Iterator{tree: tree, node: nil}
return Iterator{tree: tree, node: nil, position: begin}
}
// 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() was called for the first time, then it will point the iterator to the first element if it exists.
// Modifies the state of the iterator.
func (iterator *Iterator) Next() bool {
if iterator.node == nil {
iterator.node = iterator.tree.Left()
return iterator.node != nil
if iterator.position == end {
goto end
}
if iterator.position == begin {
left := iterator.tree.Left()
if left == nil {
goto end
}
iterator.node = left
goto between
}
if iterator.node.Right != nil {
iterator.node = iterator.node.Right
for iterator.node.Left != nil {
iterator.node = iterator.node.Left
}
return true
goto between
}
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
goto between
}
}
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
}
end:
iterator.node = nil
iterator.position = end
return false
between:
iterator.position = between
return true
}
// 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().
// If Prev() returns true, then previous element's key 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.position == begin {
goto begin
}
if iterator.position == end {
right := iterator.tree.Right()
if right == nil {
goto begin
}
iterator.node = right
goto between
}
if iterator.node.Left != nil {
iterator.node = iterator.node.Left
for iterator.node.Right != nil {
iterator.node = iterator.node.Right
}
return true
goto between
}
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
goto between
}
}
iterator.node = node // fix: if parent didn't satisfy the comparator criteria
}
begin:
iterator.node = nil
iterator.position = begin
return false
between:
iterator.position = between
return true
}
// Value returns the current element's value.
@ -356,6 +393,36 @@ func (iterator *Iterator) Key() interface{} {
return iterator.node.Key
}
// Begin resets the iterator to its initial state (one-before-first)
// Call Next() to fetch the first element if any.
func (iterator *Iterator) Begin() {
iterator.node = nil
iterator.position = begin
}
// End moves the iterator past the last element (one-past-the-end).
// Call Prev() to fetch the last element if any.
func (iterator *Iterator) End() {
iterator.node = nil
iterator.position = end
}
// First moves the iterator to the first element and returns true if there was a first element in the container.
// If First() returns true, then first element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator
func (iterator *Iterator) First() bool {
iterator.Begin()
return iterator.Next()
}
// Last moves the iterator to the last element and returns true if there was a last element in the container.
// If Last() returns true, then last element's key and value can be retrieved by Key() and Value().
// Modifies the state of the iterator.
func (iterator *Iterator) Last() bool {
iterator.End()
return iterator.Prev()
}
// String returns a string representation of container
func (tree *Tree) String() string {
str := "RedBlackTree\n"

View File

@ -282,7 +282,6 @@ func TestRedBlackTreeIterator1Prev(t *testing.T) {
}
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
@ -294,9 +293,9 @@ func TestRedBlackTreeIterator1Prev(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
@ -337,7 +336,6 @@ func TestRedBlackTreeIterator2Prev(t *testing.T) {
}
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
@ -349,9 +347,9 @@ func TestRedBlackTreeIterator2Prev(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
@ -388,7 +386,6 @@ func TestRedBlackTreeIterator3Prev(t *testing.T) {
}
countDown := tree.size
for it.Prev() {
countDown--
key := it.Key()
switch key {
case countDown:
@ -400,9 +397,9 @@ func TestRedBlackTreeIterator3Prev(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
countDown--
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := countDown, 1; actualValue != expectedValue {
if actualValue, expectedValue := countDown, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
@ -450,7 +447,7 @@ func TestRedBlackTreeIterator4Next(t *testing.T) {
}
}
func TestRedBlackTreeIterator4(t *testing.T) {
func TestRedBlackTreeIterator4Prev(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(13, 5)
tree.Put(8, 3)
@ -477,7 +474,6 @@ func TestRedBlackTreeIterator4(t *testing.T) {
for it.Next() {
}
for it.Prev() {
count--
value := it.Value()
switch value {
case count:
@ -489,13 +485,100 @@ func TestRedBlackTreeIterator4(t *testing.T) {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
}
count--
}
// one less that in Next(), thus "1"
if actualValue, expectedValue := count, 1; actualValue != expectedValue {
if actualValue, expectedValue := count, 0; actualValue != expectedValue {
t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue)
}
}
func TestRedBlackTreeIteratorBegin(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Begin()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
for it.Next() {
}
it.Begin()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Next()
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestRedBlackTreeIteratorEnd(t *testing.T) {
tree := NewWithIntComparator()
it := tree.Iterator()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.End()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it.End()
if it.node != nil {
t.Errorf("Got %v expected %v", it.node, nil)
}
it.Prev()
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func TestRedBlackTreeIteratorFirst(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.First(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 1 || value != "a" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a")
}
}
func TestRedBlackTreeIteratorLast(t *testing.T) {
tree := NewWithIntComparator()
tree.Put(3, "c")
tree.Put(1, "a")
tree.Put(2, "b")
it := tree.Iterator()
if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue {
t.Errorf("Got %v expected %v", actualValue, expectedValue)
}
if key, value := it.Key(), it.Value(); key != 3 || value != "c" {
t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c")
}
}
func BenchmarkRedBlackTree(b *testing.B) {
for i := 0; i < b.N; i++ {
tree := NewWithIntComparator()