Skip to content

Commit

Permalink
Merge pull request #2 from li1234yun/trees_any_type_value
Browse files Browse the repository at this point in the history
Modify trees value generic type to any for allowing receive map/slice etc
  • Loading branch information
ugurcsen authored Apr 26, 2023
2 parents 070cec7 + facb43e commit 95753c5
Show file tree
Hide file tree
Showing 10 changed files with 43 additions and 38 deletions.
3 changes: 2 additions & 1 deletion examples/redblacktreeextended/redblacktreeextended.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ package redblacktreeextended

import (
"fmt"

rbt "github.com/ugurcsen/gods-generic/trees/redblacktree"
)

// RedBlackTreeExtended to demonstrate how to extend a RedBlackTree to include new functions
type RedBlackTreeExtended[K, T comparable] struct {
type RedBlackTreeExtended[K comparable, T any] struct {
*rbt.Tree[K, T]
}

Expand Down
25 changes: 13 additions & 12 deletions trees/avltree/avltree.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package avltree

import (
"fmt"

"github.com/ugurcsen/gods-generic/trees"
"github.com/ugurcsen/gods-generic/utils"
)
Expand All @@ -19,14 +20,14 @@ import (
var _ trees.Tree[int] = new(Tree[int, int])

// Tree holds elements of the AVL tree.
type Tree[K, T comparable] struct {
type Tree[K comparable, T any] struct {
Root *Node[K, T] // Root node
Comparator utils.Comparator[K] // Key comparator
size int // Total number of keys in the tree
}

// Node is a single element within the tree
type Node[K, T comparable] struct {
type Node[K comparable, T any] struct {
Key K
Value T
Parent *Node[K, T] // Parent node
Expand All @@ -35,17 +36,17 @@ type Node[K, T comparable] struct {
}

// NewWith instantiates an AVL tree with the custom comparator.
func NewWith[K, T comparable](comparator utils.Comparator[K]) *Tree[K, T] {
func NewWith[K comparable, T any](comparator utils.Comparator[K]) *Tree[K, T] {
return &Tree[K, T]{Comparator: comparator}
}

// NewWithNumberComparator instantiates an AVL tree with the IntComparator, i.e. keys are of type int.
func NewWithNumberComparator[T comparable]() *Tree[int, T] {
func NewWithNumberComparator[T any]() *Tree[int, T] {
return &Tree[int, T]{Comparator: utils.NumberComparator[int]}
}

// NewWithStringComparator instantiates an AVL tree with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator[T comparable]() *Tree[string, T] {
func NewWithStringComparator[T any]() *Tree[string, T] {
return &Tree[string, T]{Comparator: utils.StringComparator}
}

Expand Down Expand Up @@ -291,7 +292,7 @@ func (t *Tree[K, T]) remove(key K, qp **Node[K, T]) bool {
return false
}

func removeMin[K, T comparable](qp **Node[K, T], minKey *K, minVal *T) bool {
func removeMin[K comparable, T any](qp **Node[K, T], minKey *K, minVal *T) bool {
q := *qp
if q.Children[0] == nil {
*minKey = q.Key
Expand All @@ -309,7 +310,7 @@ func removeMin[K, T comparable](qp **Node[K, T], minKey *K, minVal *T) bool {
return false
}

func putFix[K, T comparable](c int8, t **Node[K, T]) bool {
func putFix[K comparable, T any](c int8, t **Node[K, T]) bool {
s := *t
if s.b == 0 {
s.b = c
Expand All @@ -330,7 +331,7 @@ func putFix[K, T comparable](c int8, t **Node[K, T]) bool {
return false
}

func removeFix[K, T comparable](c int8, t **Node[K, T]) bool {
func removeFix[K comparable, T any](c int8, t **Node[K, T]) bool {
s := *t
if s.b == 0 {
s.b = c
Expand Down Expand Up @@ -359,14 +360,14 @@ func removeFix[K, T comparable](c int8, t **Node[K, T]) bool {
return true
}

func singlerot[K, T comparable](c int8, s *Node[K, T]) *Node[K, T] {
func singlerot[K comparable, T any](c int8, s *Node[K, T]) *Node[K, T] {
s.b = 0
s = rotate(c, s)
s.b = 0
return s
}

func doublerot[K, T comparable](c int8, s *Node[K, T]) *Node[K, T] {
func doublerot[K comparable, T any](c int8, s *Node[K, T]) *Node[K, T] {
a := (c + 1) / 2
r := s.Children[a]
s.Children[a] = rotate(-c, s.Children[a])
Expand All @@ -388,7 +389,7 @@ func doublerot[K, T comparable](c int8, s *Node[K, T]) *Node[K, T] {
return p
}

func rotate[K, T comparable](c int8, s *Node[K, T]) *Node[K, T] {
func rotate[K comparable, T any](c int8, s *Node[K, T]) *Node[K, T] {
a := (c + 1) / 2
r := s.Children[a]
s.Children[a] = r.Children[a^1]
Expand Down Expand Up @@ -446,7 +447,7 @@ func (n *Node[K, T]) walk1(a int) *Node[K, T] {
return p
}

func output[K, T comparable](node *Node[K, T], prefix string, isTail bool, str *string) {
func output[K comparable, T any](node *Node[K, T], prefix string, isTail bool, str *string) {
if node.Children[1] != nil {
newPrefix := prefix
if isTail {
Expand Down
6 changes: 3 additions & 3 deletions trees/avltree/avltree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ package avltree
import (
"encoding/json"
"fmt"
"github.com/ugurcsen/gods-generic/utils"
"strings"
"testing"

"github.com/ugurcsen/gods-generic/utils"
)

func TestAVLTreeGet(t *testing.T) {
Expand Down Expand Up @@ -657,8 +658,7 @@ func TestAVLTreeIteratorPrevTo(t *testing.T) {
}

func TestAVLTreeSerialization(t *testing.T) {
tree := NewWith[string, string](utils.StringComparator)
tree = NewWithStringComparator[string]()
tree := NewWithStringComparator[string]()
tree.Put("c", "3")
tree.Put("b", "2")
tree.Put("a", "1")
Expand Down
2 changes: 1 addition & 1 deletion trees/avltree/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "github.com/ugurcsen/gods-generic/containers"
var _ containers.ReverseIteratorWithKey[int, int] = (*Iterator[int, int])(nil)

// Iterator holding the iterator's state
type Iterator[K, T comparable] struct {
type Iterator[K comparable, T any] struct {
tree *Tree[K, T]
node *Node[K, T]
position position
Expand Down
2 changes: 1 addition & 1 deletion trees/binaryheap/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (iterator *Iterator[T]) Value() T {
if end > iterator.heap.Size() {
end = iterator.heap.Size()
}
tmpHeap := NewWith[T](iterator.heap.Comparator)
tmpHeap := NewWith(iterator.heap.Comparator)
for n := start; n < end; n++ {
value, _ := iterator.heap.list.Get(n)
tmpHeap.Push(value)
Expand Down
17 changes: 9 additions & 8 deletions trees/btree/btree.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,50 +19,51 @@ package btree
import (
"bytes"
"fmt"
"strings"

"github.com/ugurcsen/gods-generic/trees"
"github.com/ugurcsen/gods-generic/utils"
"strings"
)

// Assert Tree implementation
var _ trees.Tree[int] = (*Tree[int, int])(nil)

// Tree holds elements of the B-tree
type Tree[K, T comparable] struct {
type Tree[K comparable, T any] struct {
Root *Node[K, T] // Root node
Comparator utils.Comparator[K] // Key comparator
size int // Total number of keys in the tree
m int // order (maximum number of children)
}

// Node is a single element within the tree
type Node[K, T comparable] struct {
type Node[K comparable, T any] struct {
Parent *Node[K, T]
Entries []*Entry[K, T] // Contained keys in node
Children []*Node[K, T] // Children nodes
}

// Entry represents the key-value pair contained within nodes
type Entry[K, T comparable] struct {
type Entry[K comparable, T any] struct {
Key K
Value T
}

// NewWith instantiates a B-tree with the order (maximum number of children) and a custom key comparator.
func NewWith[K, T comparable](order int, comparator utils.Comparator[K]) *Tree[K, T] {
func NewWith[K comparable, T any](order int, comparator utils.Comparator[K]) *Tree[K, T] {
if order < 3 {
panic("Invalid order, should be at least 3")
}
return &Tree[K, T]{m: order, Comparator: comparator}
}

// NewWithNumberComparator instantiates a B-tree with the order (maximum number of children) and the IntComparator, i.e. keys are of type int.
func NewWithNumberComparator[T comparable](order int) *Tree[int, T] {
func NewWithNumberComparator[T any](order int) *Tree[int, T] {
return NewWith[int, T](order, utils.NumberComparator[int])
}

// NewWithStringComparator instantiates a B-tree with the order (maximum number of children) and the StringComparator, i.e. keys are of type string.
func NewWithStringComparator[T comparable](order int) *Tree[string, T] {
func NewWithStringComparator[T any](order int) *Tree[string, T] {
return NewWith[string, T](order, utils.StringComparator)
}

Expand Down Expand Up @@ -415,7 +416,7 @@ func (tree *Tree[K, T]) splitRoot() {
tree.Root = newRoot
}

func setParent[K, T comparable](nodes []*Node[K, T], parent *Node[K, T]) {
func setParent[K comparable, T any](nodes []*Node[K, T], parent *Node[K, T]) {
for _, node := range nodes {
node.Parent = parent
}
Expand Down
7 changes: 4 additions & 3 deletions trees/btree/btree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ package btree
import (
"encoding/json"
"fmt"
"github.com/ugurcsen/gods-generic/utils"
"strings"
"testing"

"github.com/ugurcsen/gods-generic/utils"
)

func TestBTreeGet1(t *testing.T) {
Expand Down Expand Up @@ -1044,13 +1045,13 @@ func TestBTreeSearch(t *testing.T) {
}
}

func assertValidTree[K, T comparable](t *testing.T, tree *Tree[K, T], expectedSize int) {
func assertValidTree[K comparable, T any](t *testing.T, tree *Tree[K, T], expectedSize int) {
if actualValue, expectedValue := tree.size, expectedSize; actualValue != expectedValue {
t.Errorf("Got %v expected %v for tree size", actualValue, expectedValue)
}
}

func assertValidTreeNode[K, T comparable](t *testing.T, node *Node[K, T], expectedEntries int, expectedChildren int, keys []K, hasParent bool) {
func assertValidTreeNode[K comparable, T any](t *testing.T, node *Node[K, T], expectedEntries int, expectedChildren int, keys []K, hasParent bool) {
if actualValue, expectedValue := node.Parent != nil, hasParent; actualValue != expectedValue {
t.Errorf("Got %v expected %v for hasParent", actualValue, expectedValue)
}
Expand Down
2 changes: 1 addition & 1 deletion trees/btree/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "github.com/ugurcsen/gods-generic/containers"
var _ containers.ReverseIteratorWithKey[int, int] = (*Iterator[int, int])(nil)

// Iterator holding the iterator's state
type Iterator[K, T comparable] struct {
type Iterator[K comparable, T any] struct {
tree *Tree[K, T]
node *Node[K, T]
entry *Entry[K, T]
Expand Down
2 changes: 1 addition & 1 deletion trees/redblacktree/iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "github.com/ugurcsen/gods-generic/containers"
var _ containers.ReverseIteratorWithKey[int, int] = (*Iterator[int, int])(nil)

// Iterator holding the iterator's state
type Iterator[K, T comparable] struct {
type Iterator[K comparable, T any] struct {
tree *Tree[K, T]
node *Node[K, T]
position position
Expand Down
15 changes: 8 additions & 7 deletions trees/redblacktree/redblacktree.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ package redblacktree

import (
"fmt"

"github.com/ugurcsen/gods-generic/trees"
"github.com/ugurcsen/gods-generic/utils"
)
Expand All @@ -27,14 +28,14 @@ const (
)

// Tree holds elements of the red-black tree
type Tree[K, T comparable] struct {
type Tree[K comparable, T any] struct {
Root *Node[K, T]
size int
Comparator utils.Comparator[K]
}

// Node is a single element within the tree
type Node[K, T comparable] struct {
type Node[K comparable, T any] struct {
Key K
Value T
color color
Expand All @@ -44,17 +45,17 @@ type Node[K, T comparable] struct {
}

// NewWith instantiates a red-black tree with the custom comparator.
func NewWith[K, T comparable](comparator utils.Comparator[K]) *Tree[K, T] {
func NewWith[K comparable, T any](comparator utils.Comparator[K]) *Tree[K, T] {
return &Tree[K, T]{Comparator: comparator}
}

// NewWithNumberComparator instantiates a red-black tree with the IntComparator, i.e. keys are of type int.
func NewWithNumberComparator[T comparable]() *Tree[int, T] {
func NewWithNumberComparator[T any]() *Tree[int, T] {
return &Tree[int, T]{Comparator: utils.NumberComparator[int]}
}

// NewWithStringComparator instantiates a red-black tree with the StringComparator, i.e. keys are of type string.
func NewWithStringComparator[T comparable]() *Tree[string, T] {
func NewWithStringComparator[T any]() *Tree[string, T] {
return &Tree[string, T]{Comparator: utils.StringComparator}
}

Expand Down Expand Up @@ -296,7 +297,7 @@ func (node *Node[K, T]) String() string {
return fmt.Sprintf("%v", node.Key)
}

func output[K, T comparable](node *Node[K, T], prefix string, isTail bool, str *string) {
func output[K comparable, T any](node *Node[K, T], prefix string, isTail bool, str *string) {
if node.Right != nil {
newPrefix := prefix
if isTail {
Expand Down Expand Up @@ -541,7 +542,7 @@ func (tree *Tree[K, T]) deleteCase6(node *Node[K, T]) {
}
}

func nodeColor[K, T comparable](node *Node[K, T]) color {
func nodeColor[K comparable, T any](node *Node[K, T]) color {
if node == nil {
return black
}
Expand Down

0 comments on commit 95753c5

Please sign in to comment.