Some fixes. Also added the readme.
This commit is contained in:
parent
cd5aa6cec7
commit
34e21699a3
5 changed files with 104 additions and 34 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
exe
|
exe
|
||||||
|
*.exe
|
||||||
|
|
8
readme
Normal file
8
readme
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# godat
|
||||||
|
|
||||||
|
Golang custom data structures for specific purposes.
|
||||||
|
|
||||||
|
- Linked list: llx
|
||||||
|
- List: listx
|
||||||
|
- Sparse array: sparsex
|
||||||
|
|
|
@ -7,18 +7,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ll := llx.New[string]()
|
ll := llx.New[string]("zero", "one", "two", "three", "four", "five")
|
||||||
ll.Append("zero")
|
|
||||||
ll.Append("one")
|
|
||||||
ll.Append("two")
|
|
||||||
ll.Append("three")
|
|
||||||
ll.Append("four")
|
|
||||||
ll.Push("minus one")
|
|
||||||
|
|
||||||
ll.Swap(1, 3)
|
ll.Swap(0, 2)
|
||||||
|
|
||||||
for p := range ll.Chan() {
|
for el := range ll.Chan() {
|
||||||
fmt.Println(p.K, p.V)
|
fmt.Println(el)
|
||||||
}
|
}
|
||||||
|
fmt.Println(ll.Slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
111
src/llx/main.go
111
src/llx/main.go
|
@ -5,10 +5,6 @@ package llx
|
||||||
// linked list than in standard library since it uses
|
// linked list than in standard library since it uses
|
||||||
// the new conception of generics.
|
// the new conception of generics.
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/mojosa-software/godat/src/iterx"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The type represents linked list data structure.
|
// The type represents linked list data structure.
|
||||||
type LinkedList[V any] struct {
|
type LinkedList[V any] struct {
|
||||||
// First empty element (not used to store values).
|
// First empty element (not used to store values).
|
||||||
|
@ -27,12 +23,15 @@ type Element[V any] struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns new empty linked list storing the V type.
|
// Returns new empty linked list storing the V type.
|
||||||
func New[V any]() *LinkedList[V] {
|
func New[V any](values ...V) *LinkedList[V] {
|
||||||
return &LinkedList[V]{
|
ret := &LinkedList[V]{
|
||||||
&Element[V]{},
|
&Element[V]{},
|
||||||
nil,
|
nil,
|
||||||
0,
|
0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret.Append(values...)
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get length of the linked list.
|
// Get length of the linked list.
|
||||||
|
@ -40,6 +39,10 @@ func (ll *LinkedList[V]) Length() int {
|
||||||
return ll.ln
|
return ll.ln
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ll *LinkedList[V]) Len() int {
|
||||||
|
return ll.Length()
|
||||||
|
}
|
||||||
|
|
||||||
// Get the index-indexed element itself.
|
// Get the index-indexed element itself.
|
||||||
func (ll *LinkedList[V]) GetEl(index int) (*Element[V], bool) {
|
func (ll *LinkedList[V]) GetEl(index int) (*Element[V], bool) {
|
||||||
if ll.ln <= index {
|
if ll.ln <= index {
|
||||||
|
@ -75,6 +78,41 @@ func (ll *LinkedList[V]) Set(i int, v V) (bool) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert the V value before the i-th element.
|
||||||
|
func (ll *LinkedList[V]) InsertBefore(v V, i int) {
|
||||||
|
if i == 0 {
|
||||||
|
ll.before = &Element[V]{
|
||||||
|
value: v,
|
||||||
|
next: ll.before.next,
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
el, ok := ll.GetEl(i-1)
|
||||||
|
if !ok {
|
||||||
|
panic("index out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
el.next = &Element[V]{
|
||||||
|
value: v,
|
||||||
|
next: el.next,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the V value after the i-th element.
|
||||||
|
func (ll *LinkedList[V]) InsertAfter(i int, v V) {
|
||||||
|
el, ok := ll.GetEl(i)
|
||||||
|
if !ok {
|
||||||
|
panic("index out of range")
|
||||||
|
}
|
||||||
|
|
||||||
|
el.next = &Element[V]{
|
||||||
|
value: v,
|
||||||
|
next: el.next,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Swap element values indexed by i1 and i2.
|
||||||
|
// Panic on "index out of range".
|
||||||
func (ll *LinkedList[V]) Swap(i1, i2 int) {
|
func (ll *LinkedList[V]) Swap(i1, i2 int) {
|
||||||
if i1 == i2 {
|
if i1 == i2 {
|
||||||
return
|
return
|
||||||
|
@ -93,16 +131,16 @@ func (ll *LinkedList[V]) Swap(i1, i2 int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes the element by its index.
|
// Deletes the element by its index.
|
||||||
func (ll *LinkedList[V]) Delete(i int) (bool) {
|
func (ll *LinkedList[V]) Delete(i int) {
|
||||||
if ll.ln <= i {
|
if ll.ln <= i && i < 0 {
|
||||||
return false
|
panic("index out of range")
|
||||||
}
|
}
|
||||||
|
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
ll.before.next =
|
ll.before.next =
|
||||||
ll.before.next.next
|
ll.before.next.next
|
||||||
ll.ln--
|
ll.ln--
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
el1, _ := ll.GetEl(i-1)
|
el1, _ := ll.GetEl(i-1)
|
||||||
|
@ -114,11 +152,22 @@ func (ll *LinkedList[V]) Delete(i int) (bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ll.ln--
|
ll.ln--
|
||||||
return true
|
}
|
||||||
|
|
||||||
|
// Alias to Delete method.
|
||||||
|
func (ll *LinkedList[V]) Del(i int) {
|
||||||
|
ll.Delete(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push in the beginning of the list.
|
// Push in the beginning of the list.
|
||||||
func (ll *LinkedList[V]) Push(v V) {
|
func (ll *LinkedList[V]) Push(values ...V) {
|
||||||
|
for _, value := range values {
|
||||||
|
ll.push(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push in the beginning of the list.
|
||||||
|
func (ll *LinkedList[V]) push(v V) {
|
||||||
prevNext := ll.before.next
|
prevNext := ll.before.next
|
||||||
nextNext := &Element[V]{
|
nextNext := &Element[V]{
|
||||||
next: prevNext,
|
next: prevNext,
|
||||||
|
@ -133,7 +182,13 @@ func (ll *LinkedList[V]) Push(v V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append to the end of the list.
|
// Append to the end of the list.
|
||||||
func (ll *LinkedList[V]) Append(v V) {
|
func (ll *LinkedList[V]) Append(values ...V) {
|
||||||
|
for _, value := range values {
|
||||||
|
ll.gappend(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ll *LinkedList[V]) gappend(v V) {
|
||||||
if ll.ln == 0 {
|
if ll.ln == 0 {
|
||||||
ll.Push(v)
|
ll.Push(v)
|
||||||
return
|
return
|
||||||
|
@ -172,22 +227,34 @@ func (ll *LinkedList[V]) Last() *Element[V] {
|
||||||
return ll.last
|
return ll.last
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a channel of Pair that contains index and the value.
|
// Returns a channel with values ordered as in list.
|
||||||
func (ll *LinkedList[V]) Chan() iterx.PairChan[int, V] {
|
func (ll *LinkedList[V]) Chan() chan V {
|
||||||
chn := make(iterx.PairChan[int, V])
|
chn := make(chan V)
|
||||||
go func(){
|
go func(){
|
||||||
i := -1
|
|
||||||
el := ll.before
|
el := ll.before
|
||||||
for el.next != nil {
|
for el.next != nil {
|
||||||
i++
|
|
||||||
el = el.next
|
el = el.next
|
||||||
chn <- iterx.Pair[int, V]{
|
chn <- el.value
|
||||||
K: i,
|
|
||||||
V: el.value,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close(chn)
|
close(chn)
|
||||||
}()
|
}()
|
||||||
return chn
|
return chn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns slice of values in the list ordered as in the list.
|
||||||
|
func (ll *LinkedList[V]) Slice() []V {
|
||||||
|
buf := make([]V, ll.Length())
|
||||||
|
chn := ll.Chan()
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for v := range chn {
|
||||||
|
buf[i] = v
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ll *LinkedList[V]) Sort() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,10 @@ type Sparse[K cons.Ordered, V any] struct {
|
||||||
// Returns new sparse array.
|
// Returns new sparse array.
|
||||||
// If shouldSort == true then it will sort the array on
|
// If shouldSort == true then it will sort the array on
|
||||||
// each change.
|
// each change.
|
||||||
func New[K cons.Ordered, V any](shouldSort bool) *Sparse[K, V] {
|
func New[K cons.Ordered, V any]() *Sparse[K, V] {
|
||||||
return &Sparse[K, V]{
|
return &Sparse[K, V]{
|
||||||
store: make(map[K] V),
|
store: make(map[K] V),
|
||||||
keys: []K{},
|
keys: []K{},
|
||||||
shouldSort: shouldSort,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue