Change queues and stacks
- Make chain element private - Remove JSON Marshaller from stack and queue - Remove access to top chain element
This commit is contained in:
parent
9870d87d41
commit
09de0a19e1
3 changed files with 18 additions and 52 deletions
|
@ -1,15 +1,15 @@
|
||||||
package containers
|
package containers
|
||||||
|
|
||||||
type ChainElem[T any] struct {
|
type chainElem[T any] struct {
|
||||||
Elem *T
|
Elem *T
|
||||||
Next *ChainElem[T]
|
Next *chainElem[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
// reachable checks if you can reach elem l when starting from elem f.
|
// reachable checks if you can reach elem l when starting from elem f.
|
||||||
// It detects loops and returns false if it runs into one.
|
// It detects loops and returns false if it runs into one.
|
||||||
func reachable[T any](f, l *ChainElem[T]) bool {
|
func reachable[T any](f, l *chainElem[T]) bool {
|
||||||
// Map to keep track of nodes already visited
|
// Map to keep track of nodes already visited
|
||||||
checks := make(map[*ChainElem[T]]bool)
|
checks := make(map[*chainElem[T]]bool)
|
||||||
for w := f; w != l; w = w.Next {
|
for w := f; w != l; w = w.Next {
|
||||||
if w == nil {
|
if w == nil {
|
||||||
return false
|
return false
|
||||||
|
@ -26,8 +26,8 @@ func reachable[T any](f, l *ChainElem[T]) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// emptyElem creates a new ChainElem[T] with empty values.
|
// emptyElem creates a new ChainElem[T] with empty values.
|
||||||
func emptyElem[T any]() *ChainElem[T] {
|
func emptyElem[T any]() *chainElem[T] {
|
||||||
return &ChainElem[T]{
|
return &chainElem[T]{
|
||||||
Elem: nil,
|
Elem: nil,
|
||||||
Next: nil,
|
Next: nil,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
package containers
|
package containers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrInvalidQueue = errors.New("invalid queue")
|
||||||
|
var ErrEmptyQueue = errors.New("empty queue")
|
||||||
|
|
||||||
type Queue[T any] struct {
|
type Queue[T any] struct {
|
||||||
head *ChainElem[T]
|
head *chainElem[T]
|
||||||
tail *ChainElem[T]
|
tail *chainElem[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValid checks if the queue is still valid.
|
// isValid checks if the queue is still valid.
|
||||||
|
@ -25,7 +27,7 @@ func (q *Queue[T]) IsEmpty() bool {
|
||||||
// Push adds a new element to the end of the queue.
|
// Push adds a new element to the end of the queue.
|
||||||
func (q *Queue[T]) Push(elem *T) error {
|
func (q *Queue[T]) Push(elem *T) error {
|
||||||
if !q.isValid() {
|
if !q.isValid() {
|
||||||
return errors.New("invalid queue")
|
return ErrInvalidQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
e := emptyElem[T]()
|
e := emptyElem[T]()
|
||||||
|
@ -40,10 +42,10 @@ func (q *Queue[T]) Push(elem *T) error {
|
||||||
// It errors out if there is no element or the queue is invalid.
|
// It errors out if there is no element or the queue is invalid.
|
||||||
func (q *Queue[T]) Pop() (*T, error) {
|
func (q *Queue[T]) Pop() (*T, error) {
|
||||||
if !q.isValid() {
|
if !q.isValid() {
|
||||||
return nil, errors.New("invalid queue")
|
return nil, ErrInvalidQueue
|
||||||
}
|
}
|
||||||
if q.IsEmpty() {
|
if q.IsEmpty() {
|
||||||
return nil, errors.New("empty queue")
|
return nil, ErrEmptyQueue
|
||||||
}
|
}
|
||||||
Elem := q.head.Elem
|
Elem := q.head.Elem
|
||||||
q.head = q.head.Next
|
q.head = q.head.Next
|
||||||
|
@ -54,38 +56,14 @@ func (q *Queue[T]) Pop() (*T, error) {
|
||||||
// It errors out if there is no element or the queue is invalid.
|
// It errors out if there is no element or the queue is invalid.
|
||||||
func (q *Queue[T]) Top() (*T, error) {
|
func (q *Queue[T]) Top() (*T, error) {
|
||||||
if !q.isValid() {
|
if !q.isValid() {
|
||||||
return nil, errors.New("queue invalid")
|
return nil, ErrInvalidQueue
|
||||||
}
|
}
|
||||||
if q.IsEmpty() {
|
if q.IsEmpty() {
|
||||||
return nil, errors.New("queue empty")
|
return nil, ErrEmptyQueue
|
||||||
}
|
}
|
||||||
return q.head.Elem, nil
|
return q.head.Elem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadElem returns the first ChainElem of the queue without removing it.
|
|
||||||
// It errors out if there is no element or the queue is invalid.
|
|
||||||
func (q *Queue[T]) HeadElem() (*ChainElem[T], error) {
|
|
||||||
if !q.isValid() {
|
|
||||||
return nil, errors.New("queue invalid")
|
|
||||||
}
|
|
||||||
if q.IsEmpty() {
|
|
||||||
return nil, errors.New("queue empty")
|
|
||||||
}
|
|
||||||
return q.head, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalJSON is used for generating json data when using json.Marshal.
|
|
||||||
func (q *Queue[T]) MarshalJSON() ([]byte, error) {
|
|
||||||
if !q.isValid() {
|
|
||||||
return nil, errors.New("queue invalid")
|
|
||||||
}
|
|
||||||
if q.IsEmpty() {
|
|
||||||
return nil, errors.New("queue empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Marshal(q.head)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BuildQueue[T any]() *Queue[T] {
|
func BuildQueue[T any]() *Queue[T] {
|
||||||
empty := emptyElem[T]()
|
empty := emptyElem[T]()
|
||||||
return &Queue[T]{
|
return &Queue[T]{
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package containers
|
package containers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Stack[T any] struct {
|
type Stack[T any] struct {
|
||||||
top *ChainElem[T]
|
top *chainElem[T]
|
||||||
bottom *ChainElem[T]
|
bottom *chainElem[T]
|
||||||
}
|
}
|
||||||
|
|
||||||
// isValid checks if the stack is valid.
|
// isValid checks if the stack is valid.
|
||||||
|
@ -61,17 +60,6 @@ func (s *Stack[T]) Top() (*T, error) {
|
||||||
return s.top.Elem, nil
|
return s.top.Elem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON is used by json.Marshal to create a json representation.
|
|
||||||
func (s *Stack[T]) MarshalJSON() ([]byte, error) {
|
|
||||||
if !s.isValid() {
|
|
||||||
return nil, errors.New("queue invalid")
|
|
||||||
}
|
|
||||||
if s.IsEmpty() {
|
|
||||||
return nil, errors.New("queue empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Marshal(s.top)
|
|
||||||
}
|
|
||||||
func BuildStack[T any]() *Stack[T] {
|
func BuildStack[T any]() *Stack[T] {
|
||||||
empty := emptyElem[T]()
|
empty := emptyElem[T]()
|
||||||
return &Stack[T]{
|
return &Stack[T]{
|
||||||
|
|
Loading…
Reference in a new issue