gods/lists/single.go

269 lines
4.5 KiB
Go
Raw Normal View History

2023-10-24 00:48:29 +03:00
package lists
import (
2024-05-19 21:19:55 +03:00
"surdeus.su/core/gods"
2023-10-24 00:48:29 +03:00
"sort"
"fmt"
)
// Linked list X .
// The package implements better variation of
// linked list than in standard library since it uses
// the new conception of generics.
2023-10-24 00:48:29 +03:00
// The type represents singly linked list data structure.
type sLinkedList[V any] struct {
// First empty element (not used to store values).
// For fast pushing.
2023-10-24 00:48:29 +03:00
before *sElement[V]
// Points to the last for fast appending.
2023-10-24 00:48:29 +03:00
last *sElement[V]
// Length.
ln int
}
2023-07-21 20:38:32 +03:00
// The type represents element of the linked list.
2023-10-24 00:48:29 +03:00
type sElement[V any] struct {
2023-11-12 12:33:46 +03:00
next *sElement[V]
value V
}
2023-10-24 00:48:29 +03:00
func newSingly[V any](values ...V) *sLinkedList[V] {
ret := &sLinkedList[V]{
before: &sElement[V]{},
2023-11-12 12:33:46 +03:00
last: nil,
ln: 0,
}
2023-08-27 15:33:44 +03:00
2023-10-24 00:48:29 +03:00
ret.Add(values...)
2023-08-27 15:33:44 +03:00
return ret
}
2023-10-24 00:48:29 +03:00
// Returns new empty linked list storing the V type.
func NewSingly[V any](values ...V) List[V] {
return newSingly[V](values...)
}
func (ll *sLinkedList[V]) Empty() bool {
2023-10-24 22:03:30 +03:00
return ll.ln == 0
2023-10-24 00:48:29 +03:00
}
func (ll *sLinkedList[V]) Size() int {
return ll.ln
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Clear() {
buf := newSingly[V]()
*ll = *buf
2023-08-27 15:33:44 +03:00
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Len() int {
2023-11-12 12:33:46 +03:00
return ll.ln
2023-10-24 00:48:29 +03:00
}
// Get the index-indexed element itself.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) getEl(index int) *sElement[V] {
if ll.ln <= index || index < 0 {
panic(gods.IndexRangeErr)
}
p := ll.before
2023-11-12 12:33:46 +03:00
for i := 0; i <= index; i++ {
p = p.next
}
2023-11-12 12:33:46 +03:00
2023-10-24 00:48:29 +03:00
return p
}
// Get the value of index-indexed element.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Get(index int) V {
return ll.getEl(index).value
}
// Set the new value in i-indexed element.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Set(i int, v V) {
el := ll.getEl(i)
el.value = v
}
2023-08-27 15:33:44 +03:00
// Insert the V value before the i-th element.
2023-10-24 22:03:30 +03:00
func (ll *sLinkedList[V]) InsB(index int, values ...V) {
if index == 0 {
ll.Put(values...)
return
}
2023-11-12 12:33:46 +03:00
el := ll.getEl(index - 1)
2023-10-24 22:03:30 +03:00
for _, v := range values {
2023-10-24 00:48:29 +03:00
el.next = &sElement[V]{
2023-08-27 15:33:44 +03:00
value: v,
2023-11-12 12:33:46 +03:00
next: el.next,
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
el = el.next
}
ll.ln += len(values)
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
func (ll *sLinkedList[V]) InsA(index int, values ...V) {
2023-10-24 22:29:00 +03:00
if index == ll.ln-1 {
ll.Add(values...)
return
}
2023-11-12 12:33:46 +03:00
2023-10-24 22:03:30 +03:00
el := ll.getEl(index)
for _, v := range values {
2023-10-24 00:48:29 +03:00
el.next = &sElement[V]{
2023-08-27 15:33:44 +03:00
value: v,
2023-11-12 12:33:46 +03:00
next: el.next,
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
el = el.next
}
ll.ln += len(values)
2023-08-27 15:33:44 +03:00
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Swap(i1, i2 int) {
if i1 == i2 {
return
}
2023-11-12 12:33:46 +03:00
2023-10-24 00:48:29 +03:00
el1 := ll.getEl(i1)
el2 := ll.getEl(i2)
2023-11-12 12:33:46 +03:00
el1.value, el2.value =
el2.value, el1.value
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Del(i int) {
2023-04-28 17:01:57 +03:00
if i == 0 {
ll.before.next =
ll.before.next.next
ll.ln--
2023-08-27 15:33:44 +03:00
return
2023-04-28 17:01:57 +03:00
}
2023-11-12 12:33:46 +03:00
el1 := ll.getEl(i - 1)
if i == ll.ln-1 {
2023-04-28 17:01:57 +03:00
el1.next = nil
} else {
2023-11-12 12:33:46 +03:00
el2 := ll.getEl(i + 1)
2023-04-28 17:01:57 +03:00
el1.next = el2
}
2023-11-12 12:33:46 +03:00
2023-04-28 17:01:57 +03:00
ll.ln--
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
func (ll *sLinkedList[V]) Put(values ...V) {
ln := len(values)
2023-11-12 12:33:46 +03:00
for i := ln - 1; i >= 0; i-- {
2023-10-24 22:03:30 +03:00
ll.Push(values[i])
}
}
func (ll *sLinkedList[V]) Pop() V {
el := ll.before.next
if el == nil {
panic(gods.IndexRangeErr)
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
ll.before.next = el.next
ll.ln--
return el.value
2023-08-27 15:33:44 +03:00
}
2023-10-24 22:03:30 +03:00
func (ll *sLinkedList[V]) Push(v V) {
prevNext := ll.before.next
2023-10-24 00:48:29 +03:00
nextNext := &sElement[V]{
2023-11-12 12:33:46 +03:00
next: prevNext,
value: v,
}
ll.before.next = nextNext
2023-11-12 12:33:46 +03:00
ll.ln++
if ll.ln == 1 {
ll.last = ll.before.next
}
}
// Append to the end of the list.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Add(values ...V) {
2023-08-27 15:33:44 +03:00
for _, value := range values {
ll.gappend(value)
}
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) gappend(v V) {
if ll.ln == 0 {
ll.Push(v)
return
}
2023-11-12 12:33:46 +03:00
2023-10-24 00:48:29 +03:00
last := &sElement[V]{
2023-11-12 12:33:46 +03:00
next: nil,
value: v,
}
2023-11-12 12:33:46 +03:00
lastBuf := ll.last
lastBuf.next = last
ll.last = last
2023-11-12 12:33:46 +03:00
ll.ln++
}
2023-07-21 20:38:32 +03:00
// Returns the first element of the linked list.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) First() *sElement[V] {
return ll.before.next
}
2023-07-21 20:38:32 +03:00
// Get elements value.
2023-10-24 00:48:29 +03:00
func (ll *sElement[V]) Value() V {
return ll.value
}
2023-07-21 20:38:32 +03:00
// Returns the next element. If the returned value == nil,
// then it is the last element.
2023-10-24 00:48:29 +03:00
func (ll *sElement[V]) Next() *sElement[V] {
return ll.next
}
2023-07-21 20:38:32 +03:00
// Returns the last element.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Last() *sElement[V] {
return ll.last
}
2023-08-27 15:33:44 +03:00
// Returns a channel with values ordered as in list.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Chan() chan V {
2023-08-27 15:33:44 +03:00
chn := make(chan V)
2023-11-12 12:33:46 +03:00
go func() {
el := ll.before
for el.next != nil {
el = el.next
2023-08-27 15:33:44 +03:00
chn <- el.value
}
close(chn)
}()
return chn
}
2023-08-27 15:33:44 +03:00
// Returns slice of values in the list ordered as in the list.
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) Values() []V {
buf := make([]V, ll.Len())
2023-08-27 15:33:44 +03:00
i := 0
2023-10-24 00:48:29 +03:00
el := ll.before
for el.next != nil {
el = el.next
buf[i] = el.value
2023-08-27 15:33:44 +03:00
i++
}
return buf
}
2023-10-24 00:48:29 +03:00
func (ll *sLinkedList[V]) String() string {
return fmt.Sprintf("%v", ll.Values())
}
func (ll *sLinkedList[V]) Sort(fn gods.LessFunc[V]) {
sort.Sort(gods.CustomSort[V]{
CustomSorter: ll,
2023-11-12 12:33:46 +03:00
LessFunc: fn,
2023-10-24 00:48:29 +03:00
})
2023-08-27 15:33:44 +03:00
}