Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c411c9f
Add ForwardIterator and ReverseIterator methods to linked list
hmcalister Dec 13, 2024
f0f2ad3
Add ForwardIterator and ReverseIterator method tests to linked list
hmcalister Dec 13, 2024
3cc1fa9
Add ForwardIterator and ReverseIterator methods to linked list queue
hmcalister Dec 13, 2024
c944b68
Add ForwardIterator and ReverseIterator method tests to linked list q…
hmcalister Dec 13, 2024
09d1a3a
Add ForwardIterator and ReverseIterator methods to linked list stack
hmcalister Dec 13, 2024
9696397
Add ForwardIterator and ReverseIterator method tests to linked list s…
hmcalister Dec 13, 2024
0fced04
Add Iterator method to hashset
hmcalister Dec 13, 2024
ebb180c
Add Iterator method tests to hashset
hmcalister Dec 13, 2024
9b2ec18
Add forward and reverse iterators to array stack
hmcalister Dec 13, 2024
94fd1b8
Add forward and reverse iterator tests to array stack
hmcalister Dec 13, 2024
804e477
Add forward and reverse iterators to array queue
hmcalister Dec 13, 2024
4219cdc
Add forward and reverse iterator tests to array queue
hmcalister Dec 13, 2024
de219e7
Add iterator method to min binary heap
hmcalister Dec 13, 2024
8494549
Add iterator method test to min binary heap
hmcalister Dec 13, 2024
74d9696
Add iterator method to max binary heap
hmcalister Dec 13, 2024
be8fbf0
Add iterator method test to max binary heap
hmcalister Dec 13, 2024
ee7295f
Add iterator method to priority queue
hmcalister Dec 13, 2024
1fb2465
Add iterator method test to priority queue
hmcalister Dec 13, 2024
4f57aa1
Add preorder, inorder, and postorder iterator to binary search tree
hmcalister Dec 13, 2024
8a377bc
Add preorder, inorder, and postorder iterator to binary search tree node
hmcalister Dec 13, 2024
bba3cde
Add preorder, inorder, and postorder iterator tests to binary search …
hmcalister Dec 13, 2024
6d9270b
Update documentation of iterator methods for BST node
hmcalister Dec 13, 2024
8199240
Add preorder, inorder, and postorder iterator to red black tree
hmcalister Dec 13, 2024
d8b6a39
Add preorder, inorder, and postorder iterator to red black tree node
hmcalister Dec 13, 2024
3e127d6
Add preorder, inorder, and postorder iterator tests to red black tree
hmcalister Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions heap/MaxBinaryHeap/maxBinaryHeap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package maxbinaryheap

import (
"iter"

comparator "github.com/hmcalister/Go-DSA/utils/Comparator"
dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
)
Expand Down Expand Up @@ -249,3 +251,22 @@ func Fold[T any, G any](heap *MaxBinaryHeap[T], initialAccumulator G, f func(ite

return accumulator
}

// Iterate over the items of the heap.
// In case it matters, the iteration is effectively in "reading order" along the heap.
// This is *not* a sorted order. To iterate in sorted order you may either extract the heap items with Items() and sort,
// or continually pop items from the heap (which will naturally update the heap).
//
// If you are updating items in the heap, please note this method does *not* reheapify.
//
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (heap *MaxBinaryHeap[T]) Iterator() iter.Seq[T] {
return func(yield func(T) bool) {
for index := 0; index < len(heap.heapData); index += 1 {
item := heap.heapData[index]
if !yield(item) {
break
}
}
}
}
13 changes: 13 additions & 0 deletions heap/MaxBinaryHeap/maxBinaryHeap_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,16 @@ func TestMaxBinaryHeapFold(t *testing.T) {
t.Errorf("expected all items to be contained in ground truth array")
}
}

func TestMaxBinaryIterator(t *testing.T) {
heap := maxbinaryheap.New[string](comparator.DefaultStringComparator)
items := []string{"a", "b", "c", "d", "e", "f", "g", "h"}
for _, item := range items {
heap.Add(item)
}

concatString := ""
for item := range heap.Iterator() {
concatString += item
}
}
21 changes: 21 additions & 0 deletions heap/MinBinaryHeap/minBinaryHeap.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package minbinaryheap

import (
"iter"

comparator "github.com/hmcalister/Go-DSA/utils/Comparator"
dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
)
Expand Down Expand Up @@ -249,3 +251,22 @@ func Fold[T any, G any](heap *MinBinaryHeap[T], initialAccumulator G, f func(ite

return accumulator
}

// Iterate over the items of the heap.
// In case it matters, the iteration is effectively in "reading order" along the heap.
// This is *not* a sorted order. To iterate in sorted order you may either extract the heap items with Items() and sort,
// or continually pop items from the heap (which will naturally update the heap).
//
// If you are updating items in the heap, please note this method does *not* reheapify.
//
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (heap *MinBinaryHeap[T]) Iterator() iter.Seq[T] {
return func(yield func(T) bool) {
for index := 0; index < len(heap.heapData); index += 1 {
item := heap.heapData[index]
if !yield(item) {
break
}
}
}
}
23 changes: 23 additions & 0 deletions heap/MinBinaryHeap/minBinaryHeap_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func TestMinBinaryHeapApply(t *testing.T) {
t.Errorf("result (%v) does not match expected result (%v)", concatString, expectedConcatString)
}
}

func TestMinBinaryHeapMap(t *testing.T) {
heap := minbinaryheap.New[string](comparator.DefaultStringComparator)
items := []string{"a", "b", "c", "d", "e", "f", "g", "h"}
Expand Down Expand Up @@ -78,3 +79,25 @@ func TestMinBinaryHeapFold(t *testing.T) {
t.Errorf("expected all items to be contained in ground truth array")
}
}

func TestMinBinaryIterator(t *testing.T) {
heap := minbinaryheap.New[string](comparator.DefaultStringComparator)
items := []string{"a", "b", "c", "d", "e", "f", "g", "h"}
for _, item := range items {
heap.Add(item)
}

concatString := ""
for item := range heap.Iterator() {
concatString += item
}

expectedConcatString := ""
for _, item := range items {
expectedConcatString += item
}

if concatString != expectedConcatString {
t.Errorf("result (%v) does not match expected result (%v)", concatString, expectedConcatString)
}
}
40 changes: 39 additions & 1 deletion list/LinkedList/linkedlist.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package linkedlist

import dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
import (
"iter"

dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
)

// An implementation of a doubly linked list.
type LinkedList[T any] struct {
Expand Down Expand Up @@ -232,6 +236,40 @@ func ReverseFold[T any, G any](list *LinkedList[T], initialAccumulator G, f func
return acc
}

// Iterate over the items of the list in the forward direction.
// Returns both the index (as counted from the head) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (list *LinkedList[T]) ForwardIterator() iter.Seq2[int, T] {
return func(yield func(int, T) bool) {
index := 0
currentNode := list.head
for currentNode != nil {
if !yield(index, currentNode.item) {
return
}
currentNode = currentNode.next
index += 1
}
}
}

// Iterate over the items of the list in the reverse direction.
// Returns both the index (as counted from the tail) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (list *LinkedList[T]) ReverseIterator() iter.Seq2[int, T] {
return func(yield func(int, T) bool) {
index := 0
currentNode := list.tail
for currentNode != nil {
if !yield(index, currentNode.item) {
return
}
currentNode = currentNode.prev
index += 1
}
}
}

// ----------------------------------------------------------------------------
// Add methods

Expand Down
45 changes: 45 additions & 0 deletions list/LinkedList/linkedlist_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,48 @@ func TestReverseFold(t *testing.T) {
t.Errorf("result (%v) does not match expected result (%v)", concatString, expectedConcatString)
}
}

func TestForwardIterator(t *testing.T) {
list := linkedlist.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
list.Add(item)
}

sum := 0
for index, item := range list.ForwardIterator() {
sum += index * item
}

expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}

func TestReverseIterator(t *testing.T) {
list := linkedlist.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
list.Add(item)
}

sum := 0
for index, item := range list.ReverseIterator() {
sum += index * item
}

slices.Reverse(items)
expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}
30 changes: 30 additions & 0 deletions queue/ArrayQueue/arrayqueue.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package arrayqueue

import (
"iter"

dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
)

Expand Down Expand Up @@ -181,3 +183,31 @@ func ReverseFold[T any, G any](queue *ArrayQueue[T], initialAccumulator G, f fun

return accumulator
}

// Iterate over the items of the queue in the forward direction (front to back).
// Returns both the index (as counted from the front of the queue) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (queue *ArrayQueue[T]) ForwardIterator() iter.Seq2[int, T] {
return func(yield func(int, T) bool) {
for index := 0; index < len(queue.queueData); index += 1 {
item := queue.queueData[index]
if !yield(index, item) {
break
}
}
}
}

// Iterate over the items of the queue in the reverse direction (back to front).
// Returns both the index (as counted from the back of the queue) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (queue *ArrayQueue[T]) ReverseIterator() iter.Seq2[int, T] {
return func(yield func(int, T) bool) {
for index := 0; index < len(queue.queueData); index += 1 {
item := queue.queueData[len(queue.queueData)-index-1]
if !yield(index, item) {
break
}
}
}
}
45 changes: 45 additions & 0 deletions queue/ArrayQueue/arrayqueue_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,48 @@ func TestReverseFold(t *testing.T) {
t.Errorf("result (%v) does not match expected result (%v)", concatString, expectedConcatString)
}
}

func TestForwardIterator(t *testing.T) {
queue := arrayqueue.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
queue.Add(item)
}

sum := 0
for index, item := range queue.ForwardIterator() {
sum += index * item
}

expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}

func TestReverseIterator(t *testing.T) {
queue := arrayqueue.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
queue.Add(item)
}

sum := 0
for index, item := range queue.ReverseIterator() {
sum += index * item
}

slices.Reverse(items)
expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}
16 changes: 16 additions & 0 deletions queue/LinkedListQueue/linkedlistqueue.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package linkedlistqueue

import (
"iter"

linkedlist "github.com/hmcalister/Go-DSA/list/LinkedList"
dsa_error "github.com/hmcalister/Go-DSA/utils/DSA_Error"
)
Expand Down Expand Up @@ -158,3 +160,17 @@ func ReverseMap[T any](queue *LinkedListQueue[T], f func(item T) T) {
func ReverseFold[T any, G any](queue *LinkedListQueue[T], initialAccumulator G, f func(item T, accumulator G) G) G {
return linkedlist.ReverseFold(queue.queueData, initialAccumulator, f)
}

// Iterate over the items of the queue in the forward direction (front to back).
// Returns both the index (from the front of the queue) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (queue *LinkedListQueue[T]) ForwardIterator() iter.Seq2[int, T] {
return queue.queueData.ForwardIterator()
}

// Iterate over the items of the queue in the reverse direction (top to bottom).
// Returns both the index from the back of the queue) and item.
// This method is not concurrency safe. For concurrent applications, consider using a mutex, or pull the data out using Items().
func (queue *LinkedListQueue[T]) ReverseIterator() iter.Seq2[int, T] {
return queue.queueData.ReverseIterator()
}
45 changes: 45 additions & 0 deletions queue/LinkedListQueue/linkedlistqueue_apply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,48 @@ func TestReverseFold(t *testing.T) {
t.Errorf("result (%v) does not match expected result (%v)", concatString, expectedConcatString)
}
}

func TestForwardIterator(t *testing.T) {
queue := linkedlistqueue.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
queue.Add(item)
}

sum := 0
for index, item := range queue.ForwardIterator() {
sum += index * item
}

expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}

func TestReverseIterator(t *testing.T) {
queue := linkedlistqueue.New[int]()
items := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
for _, item := range items {
queue.Add(item)
}

sum := 0
for index, item := range queue.ReverseIterator() {
sum += index * item
}

slices.Reverse(items)
expectedSum := 0
for index, item := range items {
expectedSum += index * item
}

if sum != expectedSum {
t.Errorf("result (%v) does not match expected result (%v)", sum, expectedSum)
}
}
Loading
Loading