finished slice stuff, started queues
parent
21e82bb2b5
commit
337e85e173
@ -0,0 +1,8 @@
|
|||||||
|
.PHONY: install_tools
|
||||||
|
install_tools:
|
||||||
|
go install github.com/google/addlicense@latest
|
||||||
|
go install github.com/jordanlewis/gcassert/cmd/gcassert@latest
|
||||||
|
|
||||||
|
.PHONY: addlicense
|
||||||
|
addlicense:
|
||||||
|
addlicense -c "Braydon Kains" -l mit .
|
@ -1,5 +1,5 @@
|
|||||||
# collections-go
|
# collections-go
|
||||||
|
|
||||||
A dependency-free package of generic Go collection data structures. Compatible with Go 1.18 and above. Strives for the most optimal solutions available with lowest number of allocations.
|
A dependency-free package of generic Go collection data structures. Compatible with Go 1.18 and above. Strives for the most optimal solutions available with lowest number of heap allocations.
|
||||||
|
|
||||||
Contributions are not currently open as this project is in active early development.
|
Contributions are not currently open as this project is in active early development.
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package collections
|
|
||||||
|
|
||||||
// A UnaryPredicate is a function that takes a single element of type
|
|
||||||
// T and returns a boolean.
|
|
||||||
type UnaryPredicate[T any] func(T) bool
|
|
||||||
|
|
||||||
// A UnaryOperator is a function that takes a single element of type
|
|
||||||
// T and returns an element of type T.
|
|
||||||
type UnaryOperator[T any] func(T) T
|
|
@ -0,0 +1,124 @@
|
|||||||
|
// Copyright (c) 2023 Braydon Kains
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
package collections
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
type LLNode[T any] struct {
|
||||||
|
Value T
|
||||||
|
Prev *LLNode[T]
|
||||||
|
Next *LLNode[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (head *LLNode[T]) Len() int {
|
||||||
|
curr := head
|
||||||
|
n := 0
|
||||||
|
for curr != nil {
|
||||||
|
n++
|
||||||
|
curr = curr.Next
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (head *LLNode[T]) Range() []T {
|
||||||
|
llLen := head.Len()
|
||||||
|
result := make([]T, llLen)
|
||||||
|
curr := head
|
||||||
|
for i := 0; i < llLen; i++ {
|
||||||
|
result[i] = curr.Value
|
||||||
|
curr = curr.Next
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (head *LLNode[T]) AddToEnd(val T) *LLNode[T] {
|
||||||
|
curr := head
|
||||||
|
for curr.Next != nil {
|
||||||
|
curr = curr.Next
|
||||||
|
}
|
||||||
|
node := &LLNode[T]{Value: val, Prev: curr}
|
||||||
|
curr.Next = node
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (head *LLNode[T]) AddToStart(val T) *LLNode[T] {
|
||||||
|
node := &LLNode[T]{Value: val, Next: head}
|
||||||
|
head.Prev = node
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *LLNode[T]) RemoveSelf() {
|
||||||
|
if n.Prev != nil {
|
||||||
|
n.Prev.Next = n.Next
|
||||||
|
}
|
||||||
|
if n.Next != nil {
|
||||||
|
n.Next.Prev = n.Prev
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A FIFO queue.
|
||||||
|
type Queue[T any] struct {
|
||||||
|
Head *LLNode[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queue[T]) Enqueue(val T) {
|
||||||
|
if q.Head == nil {
|
||||||
|
q.Head = &LLNode[T]{Value: val}
|
||||||
|
} else {
|
||||||
|
q.Head.AddToEnd(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrQueueEmpty = errors.New("collections: the queue is empty")
|
||||||
|
|
||||||
|
func (q *Queue[T]) Dequeue() (T, error) {
|
||||||
|
if q.Head == nil {
|
||||||
|
return *new(T), ErrQueueEmpty
|
||||||
|
}
|
||||||
|
result := q.Head
|
||||||
|
q.Head = result.Next
|
||||||
|
return result.Value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Stack, aka FILO queue.
|
||||||
|
type Stack[T any] struct {
|
||||||
|
Head *LLNode[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stack[T]) Push(val T) {
|
||||||
|
if s.Head == nil {
|
||||||
|
s.Head = &LLNode[T]{Value: val}
|
||||||
|
} else {
|
||||||
|
node := s.Head.AddToStart(val)
|
||||||
|
s.Head = node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ErrStackEmpty = errors.New("the stack is empty")
|
||||||
|
|
||||||
|
func (s *Stack[T]) Pop() (T, error) {
|
||||||
|
if s.Head == nil {
|
||||||
|
return *new(T), ErrStackEmpty
|
||||||
|
}
|
||||||
|
oldHead := s.Head
|
||||||
|
s.Head = s.Head.Next
|
||||||
|
oldHead.RemoveSelf()
|
||||||
|
return oldHead.Value, nil
|
||||||
|
}
|
Loading…
Reference in New Issue