A little datastructures

pull/1/head
Drew Bednar 4 months ago
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…
Cancel
Save