A little datastructures
parent
2150188501
commit
c4e7f0d5ea
@ -0,0 +1,7 @@
|
||||
# Basic Data Structures
|
||||
|
||||
These are basic implementations of standard data structures. They are not thread safe implementations. To avoid race conditions you would need to use a mutex (mutual exclusion lock) to lock the data structure before any reads or writes. The `sync` package has a `RWMutex` that can be used.
|
||||
|
||||
|
||||
## Example of using Mutex
|
||||
|
@ -0,0 +1,41 @@
|
||||
package datastructures
|
||||
|
||||
import "errors"
|
||||
|
||||
// Queue a First in First out data structure.
|
||||
type Queue struct {
|
||||
elements []any
|
||||
}
|
||||
|
||||
// Enqueue adds and element to the queue
|
||||
func (q *Queue) Enqueue(el any) {
|
||||
q.elements = append(q.elements, el)
|
||||
}
|
||||
|
||||
// Dequeue removes an element from the queue
|
||||
func (q *Queue) Dequeue() (any, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("empty queue")
|
||||
}
|
||||
el := q.elements[0]
|
||||
q.elements = q.elements[1:]
|
||||
return el, nil
|
||||
}
|
||||
|
||||
// Peek retrieves a copy of the next element in the queue.
|
||||
func (q *Queue) Peek() (any, error) {
|
||||
if q.IsEmpty() {
|
||||
return nil, errors.New("empty queue")
|
||||
}
|
||||
return q.elements[0], nil
|
||||
}
|
||||
|
||||
// IsEmpty checks if the queue has any elements
|
||||
func (q *Queue) IsEmpty() bool {
|
||||
return q.Size() == 0
|
||||
}
|
||||
|
||||
// Size checks the size of the queue
|
||||
func (q *Queue) Size() int {
|
||||
return len(q.elements)
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package datastructures
|
||||
|
||||
type Set struct {
|
||||
elements map[any]bool
|
||||
}
|
||||
|
||||
func (s *Set) Add(el any) {
|
||||
s.elements[el] = true
|
||||
}
|
||||
|
||||
func (s *Set) Remove(el any) {
|
||||
delete(s.elements, el)
|
||||
}
|
||||
|
||||
func (s *Set) IsEmpty() bool {
|
||||
return s.Size() == 0
|
||||
}
|
||||
|
||||
func (s *Set) Size() int {
|
||||
return len(s.elements)
|
||||
}
|
||||
|
||||
func (s *Set) Has(el any) bool {
|
||||
_, ok := s.elements[el]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (s *Set) Difference(set Set) Set {
|
||||
d := s.Copy()
|
||||
for k := range d.elements {
|
||||
if set.Has(k) {
|
||||
d.Remove(k)
|
||||
}
|
||||
}
|
||||
|
||||
return d
|
||||
}
|
||||
|
||||
func (s *Set) IsSubset(t Set) bool {
|
||||
for k := range s.elements {
|
||||
if !t.Has(k) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *Set) List() []any {
|
||||
list := make([]any, s.Size())
|
||||
for k := range s.elements {
|
||||
list = append(list, k)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func (s *Set) Copy() Set {
|
||||
c := NewSet()
|
||||
for k := range s.elements {
|
||||
c.Add(k)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// NewSet creates a new instance of Set
|
||||
func NewSet() Set {
|
||||
return Set{elements: make(map[any]bool)}
|
||||
}
|
||||
|
||||
// Union determines the OR relationship on all sets under consideration
|
||||
func Union(sets ...Set) Set {
|
||||
u := sets[0].Copy()
|
||||
for _, set := range sets[1:] {
|
||||
for k := range set.elements {
|
||||
u.Add(k)
|
||||
}
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// Intersection determines the AND relationship of all sets under consideration
|
||||
func Intersection(sets ...Set) Set {
|
||||
i := sets[0].Copy()
|
||||
for k := range i.elements {
|
||||
for _, set := range sets[1:] {
|
||||
if !set.Has(k) {
|
||||
i.Remove(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package datastructures
|
||||
|
||||
import "errors"
|
||||
|
||||
// Stack a Last in First out data structure.
|
||||
type Stack struct {
|
||||
elements []any
|
||||
}
|
||||
|
||||
// Push add an element to the top of the stack
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// any: an element to add to the top of the stack.
|
||||
func (s *Stack) Push(el any) {
|
||||
s.elements = append(s.elements, el)
|
||||
}
|
||||
|
||||
// Pop removes and returns the top element of the stack.
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// any: The top element of the stack
|
||||
//
|
||||
// error: If the stack is found to be empty
|
||||
func (s *Stack) Pop() (any, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("empty stack")
|
||||
}
|
||||
el := s.elements[len(s.elements)-1]
|
||||
s.elements = s.elements[:len(s.elements)-1]
|
||||
return el, nil
|
||||
}
|
||||
|
||||
// Peek checks the top item in the stack.
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// any: a copy of the top element
|
||||
//
|
||||
// error: An error if the stack is empty
|
||||
func (s *Stack) Peek() (any, error) {
|
||||
if s.IsEmpty() {
|
||||
return nil, errors.New("empty stack")
|
||||
}
|
||||
|
||||
return s.elements[len(s.elements)-1], nil
|
||||
}
|
||||
|
||||
// IsEmpty checks if the stack contains any elements.
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// bool: True is the stack is empty. False if the stack contains elements.
|
||||
func (s *Stack) IsEmpty() bool {
|
||||
return s.Size() == 0
|
||||
}
|
||||
|
||||
// Size checks this size of the stack
|
||||
//
|
||||
// Returns:
|
||||
//
|
||||
// int: The number of elements on the stack
|
||||
func (s *Stack) Size() int {
|
||||
return len(s.elements)
|
||||
}
|
Loading…
Reference in New Issue