Compare commits

...

2 Commits

Author SHA1 Message Date
fb3012448d ring implemented 2023-07-10 17:16:51 +02:00
0b5f57e0c2 fixed generic types for data structures implemented via lists 2023-07-10 17:16:41 +02:00
16 changed files with 171 additions and 35 deletions

0
go.sum Normal file
View File

View File

@ -30,6 +30,11 @@ func (s *ArrayList[T]) Get(index int) T {
return s.values[index]
}
func (s *ArrayList[T]) Set(index int, value T) {
s.init()
s.values[index] = value
}
func (s *ArrayList[T]) RemoveAt(index int) T {
s.init()
ret := s.values[index]

View File

@ -1,5 +1,7 @@
package ds
import "fmt"
type LinkedList[T any] struct {
head *linkedListNode[T]
tail *linkedListNode[T]
@ -8,8 +10,8 @@ type LinkedList[T any] struct {
var _ List[int] = &LinkedList[int]{}
func NewLinkedList[T any]() *ArrayList[T] {
return &ArrayList[T]{}
func NewLinkedList[T any]() *LinkedList[T] {
return &LinkedList[T]{}
}
func (l *LinkedList[T]) Add(value T) {
@ -37,6 +39,10 @@ func (l *LinkedList[T]) Get(index int) T {
return l.getNode(index).value
}
func (l *LinkedList[T]) Set(index int, value T) {
l.getNode(index).value = value
}
func (l *LinkedList[T]) RemoveAt(index int) T {
node := l.getNode(index)
@ -79,6 +85,10 @@ func (l *LinkedList[T]) Empty() bool {
}
func (l *LinkedList[T]) getNode(index int) *linkedListNode[T] {
if index < 0 || index > l.length {
panic(fmt.Sprintf("invalid index %d for list with size %d", index, l.Size()))
}
if index == 0 {
return l.head
}

View File

@ -1,7 +1,7 @@
package ds
type ArrayQueue[T any] struct {
*ListQueue[T]
*ListQueue[T, *ArrayList[T]]
}
var _ Queue[int] = &ArrayQueue[int]{}

View File

@ -1,7 +1,7 @@
package ds
type LinkedListQueue[T any] struct {
*ListQueue[T]
*ListQueue[T, *LinkedList[T]]
}
var _ Queue[int] = &LinkedListQueue[int]{}

View File

@ -1,47 +1,47 @@
package ds
type ListQueue[T any] struct {
list List[T]
type ListQueue[T any, L List[T]] struct {
list L
}
var _ Queue[int] = &ListQueue[int]{}
var _ Queue[int] = &ListQueue[int, List[int]]{}
func NewListQueue[T any](list List[T]) *ListQueue[T] {
return &ListQueue[T]{list}
func NewListQueue[T any, L List[T]](list L) *ListQueue[T, L] {
return &ListQueue[T, L]{list}
}
func (s *ListQueue[T]) Enqueue(value T) {
func (s *ListQueue[T, L]) Enqueue(value T) {
s.list.Add(value)
}
func (s *ListQueue[T]) Add(value T) {
func (s *ListQueue[T, L]) Add(value T) {
s.Enqueue(value)
}
func (s *ListQueue[T]) AddAll(values Iterable[T]) {
func (s *ListQueue[T, L]) AddAll(values Iterable[T]) {
values.Each(s.Add)
}
func (s *ListQueue[T]) Dequeue() T {
func (s *ListQueue[T, L]) Dequeue() T {
return s.list.RemoveAt(0)
}
func (s *ListQueue[T]) Peek() T {
func (s *ListQueue[T, L]) Peek() T {
return s.PeekAt(0)
}
func (s *ListQueue[T]) PeekAt(index int) T {
func (s *ListQueue[T, L]) PeekAt(index int) T {
return s.list.Get(index)
}
func (s *ListQueue[T]) Size() int {
func (s *ListQueue[T, L]) Size() int {
return s.list.Size()
}
func (s *ListQueue[T]) Empty() bool {
func (s *ListQueue[T, L]) Empty() bool {
return s.Size() == 0
}
func (s *ListQueue[T]) Clear() {
func (s *ListQueue[T, L]) Clear() {
s.list.Clear()
}

13
impl_ring_array.go Normal file
View File

@ -0,0 +1,13 @@
package ds
type ArrayRing[T any] struct {
*ListRing[T, *ArrayList[*T]]
}
var _ Ring[int] = &ArrayRing[int]{}
func NewArrayRing[T any](size int) *ArrayRing[T] {
return &ArrayRing[T]{
ListRing: NewListRing[T](NewArrayList[*T](size), size),
}
}

13
impl_ring_linked_list.go Normal file
View File

@ -0,0 +1,13 @@
package ds
type LinkedListRing[T any] struct {
*ListRing[T, *LinkedList[*T]]
}
var _ Ring[int] = &LinkedListRing[int]{}
func NewLinkedListRing[T any](size int) *LinkedListRing[T] {
return &LinkedListRing[T]{
ListRing: NewListRing[T](NewLinkedList[*T](), size),
}
}

65
impl_ring_list.go Normal file
View File

@ -0,0 +1,65 @@
package ds
type ListRing[T any, L List[*T]] struct {
list L
current int
}
var _ Ring[int] = &ListRing[int, List[*int]]{}
func NewListRing[T any, L List[*T]](list L, size int) *ListRing[T, L] {
preAllocList[*T, List[*T]](list, nil, size)
return &ListRing[T, L]{
list: list,
current: 0,
}
}
func (r *ListRing[T, L]) Next() Ring[T] {
return &ListRing[T, L]{
list: r.list,
current: modAbs(r.current+1, r.list.Size()),
}
}
func (r *ListRing[T, L]) Prev() Ring[T] {
return &ListRing[T, L]{
list: r.list,
current: modAbs(r.current-1, r.list.Size()),
}
}
func (r *ListRing[T, L]) Set(v T) {
r.list.Set(r.current, &v)
}
func (r *ListRing[T, L]) Has() bool {
return r.list.Get(r.current) != nil
}
func (r *ListRing[T, L]) Get() (T, bool) {
if !r.Has() {
return *new(T), false
}
return *r.list.Get(r.current), true
}
func (r *ListRing[T, L]) GetOrDefault(defaultValue T) T {
value, ok := r.Get()
if !ok {
return defaultValue
}
return value
}
func (r *ListRing[T, L]) Each(f func(value *T)) {
var t Ring[T] = r
for i := 0; i < r.list.Size(); i++ {
if value, ok := t.Get(); ok {
f(&value)
} else {
f(nil)
}
t = t.Next()
}
}

View File

@ -1,7 +1,7 @@
package ds
type ArrayStack[T any] struct {
*ListStack[T]
*ListStack[T, *ArrayList[T]]
}
var _ Stack[int] = &ArrayStack[int]{}

View File

@ -1,7 +1,7 @@
package ds
type LinkedListStack[T any] struct {
*ListStack[T]
*ListStack[T, *LinkedList[T]]
}
var _ Stack[int] = &LinkedListStack[int]{}

View File

@ -1,47 +1,47 @@
package ds
type ListStack[T any] struct {
list List[T]
type ListStack[T any, L List[T]] struct {
list L
}
var _ Stack[int] = &ListStack[int]{}
var _ Stack[int] = &ListStack[int, List[int]]{}
func NewListStack[T any](list List[T]) *ListStack[T] {
return &ListStack[T]{list}
func NewListStack[T any, L List[T]](list L) *ListStack[T, L] {
return &ListStack[T, L]{list}
}
func (s *ListStack[T]) Push(value T) {
func (s *ListStack[T, L]) Push(value T) {
s.list.Add(value)
}
func (s *ListStack[T]) Add(value T) {
func (s *ListStack[T, L]) Add(value T) {
s.Push(value)
}
func (s *ListStack[T]) AddAll(values Iterable[T]) {
func (s *ListStack[T, L]) AddAll(values Iterable[T]) {
values.Each(s.Add)
}
func (s *ListStack[T]) Pop() T {
func (s *ListStack[T, L]) Pop() T {
return s.list.RemoveAt(s.list.Size() - 1)
}
func (s *ListStack[T]) Peek() T {
func (s *ListStack[T, L]) Peek() T {
return s.PeekAt(s.Size() - 1)
}
func (s *ListStack[T]) PeekAt(index int) T {
func (s *ListStack[T, L]) PeekAt(index int) T {
return s.list.Get(index)
}
func (s *ListStack[T]) Size() int {
func (s *ListStack[T, L]) Size() int {
return s.list.Size()
}
func (s *ListStack[T]) Empty() bool {
func (s *ListStack[T, L]) Empty() bool {
return s.Size() == 0
}
func (s *ListStack[T]) Clear() {
func (s *ListStack[T, L]) Clear() {
s.list.Clear()
}

View File

@ -1,2 +1,3 @@
package ds
// TODO
// TODO

13
int_ring.go Normal file
View File

@ -0,0 +1,13 @@
package ds
type Ring[T any] interface {
Iterable[*T]
Next() Ring[T]
Prev() Ring[T]
Set(T)
Has() bool
Get() (T, bool)
GetOrDefault(defaultValue T) T
}

View File

@ -11,6 +11,7 @@ type Retrievable[T comparable] interface {
type Indexable[K comparable, T any] interface {
Get(index K) T
Set(index K, value T)
}
type IndexedRemovable[K comparable, T any] interface {

15
utils.go Normal file
View File

@ -0,0 +1,15 @@
package ds
func modAbs(a, b int) int {
v := a % b
if v < 0 {
return b + v
}
return v
}
func preAllocList[T any, L List[T]](list L, value T, size int) {
for list.Size() < size {
list.Add(value)
}
}