123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- package lists
- import (
- "surdeus.su/core/gods"
- "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.
- // The type represents singly linked list data structure.
- type sLinkedList[V any] struct {
- // First empty element (not used to store values).
- // For fast pushing.
- before *sElement[V]
- // Points to the last for fast appending.
- last *sElement[V]
- // Length.
- ln int
- }
- // The type represents element of the linked list.
- type sElement[V any] struct {
- next *sElement[V]
- value V
- }
- func newSingly[V any](values ...V) *sLinkedList[V] {
- ret := &sLinkedList[V]{
- before: &sElement[V]{},
- last: nil,
- ln: 0,
- }
- ret.Add(values...)
- return ret
- }
- // 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 {
- return ll.ln == 0
- }
- func (ll *sLinkedList[V]) Size() int {
- return ll.ln
- }
- func (ll *sLinkedList[V]) Clear() {
- buf := newSingly[V]()
- *ll = *buf
- }
- func (ll *sLinkedList[V]) Len() int {
- return ll.ln
- }
- // Get the index-indexed element itself.
- func (ll *sLinkedList[V]) getEl(index int) *sElement[V] {
- if ll.ln <= index || index < 0 {
- panic(gods.IndexRangeErr)
- }
- p := ll.before
- for i := 0; i <= index; i++ {
- p = p.next
- }
- return p
- }
- // Get the value of index-indexed element.
- func (ll *sLinkedList[V]) Get(index int) V {
- return ll.getEl(index).value
- }
- // Set the new value in i-indexed element.
- func (ll *sLinkedList[V]) Set(i int, v V) {
- el := ll.getEl(i)
- el.value = v
- }
- // Insert the V value before the i-th element.
- func (ll *sLinkedList[V]) InsB(index int, values ...V) {
- if index == 0 {
- ll.Put(values...)
- return
- }
- el := ll.getEl(index - 1)
- for _, v := range values {
- el.next = &sElement[V]{
- value: v,
- next: el.next,
- }
- el = el.next
- }
- ll.ln += len(values)
- }
- func (ll *sLinkedList[V]) InsA(index int, values ...V) {
- if index == ll.ln-1 {
- ll.Add(values...)
- return
- }
- el := ll.getEl(index)
- for _, v := range values {
- el.next = &sElement[V]{
- value: v,
- next: el.next,
- }
- el = el.next
- }
- ll.ln += len(values)
- }
- func (ll *sLinkedList[V]) Swap(i1, i2 int) {
- if i1 == i2 {
- return
- }
- el1 := ll.getEl(i1)
- el2 := ll.getEl(i2)
- el1.value, el2.value =
- el2.value, el1.value
- }
- func (ll *sLinkedList[V]) Del(i int) {
- if i == 0 {
- ll.before.next =
- ll.before.next.next
- ll.ln--
- return
- }
- el1 := ll.getEl(i - 1)
- if i == ll.ln-1 {
- el1.next = nil
- } else {
- el2 := ll.getEl(i + 1)
- el1.next = el2
- }
- ll.ln--
- }
- func (ll *sLinkedList[V]) Put(values ...V) {
- ln := len(values)
- for i := ln - 1; i >= 0; i-- {
- ll.Push(values[i])
- }
- }
- func (ll *sLinkedList[V]) Pop() V {
- el := ll.before.next
- if el == nil {
- panic(gods.IndexRangeErr)
- }
- ll.before.next = el.next
- ll.ln--
- return el.value
- }
- func (ll *sLinkedList[V]) Push(v V) {
- prevNext := ll.before.next
- nextNext := &sElement[V]{
- next: prevNext,
- value: v,
- }
- ll.before.next = nextNext
- ll.ln++
- if ll.ln == 1 {
- ll.last = ll.before.next
- }
- }
- // Append to the end of the list.
- func (ll *sLinkedList[V]) Add(values ...V) {
- for _, value := range values {
- ll.gappend(value)
- }
- }
- func (ll *sLinkedList[V]) gappend(v V) {
- if ll.ln == 0 {
- ll.Push(v)
- return
- }
- last := &sElement[V]{
- next: nil,
- value: v,
- }
- lastBuf := ll.last
- lastBuf.next = last
- ll.last = last
- ll.ln++
- }
- // Returns the first element of the linked list.
- func (ll *sLinkedList[V]) First() *sElement[V] {
- return ll.before.next
- }
- // Get elements value.
- func (ll *sElement[V]) Value() V {
- return ll.value
- }
- // Returns the next element. If the returned value == nil,
- // then it is the last element.
- func (ll *sElement[V]) Next() *sElement[V] {
- return ll.next
- }
- // Returns the last element.
- func (ll *sLinkedList[V]) Last() *sElement[V] {
- return ll.last
- }
- // Returns a channel with values ordered as in list.
- func (ll *sLinkedList[V]) Chan() chan V {
- chn := make(chan V)
- go func() {
- el := ll.before
- for el.next != nil {
- el = el.next
- chn <- el.value
- }
- close(chn)
- }()
- return chn
- }
- // Returns slice of values in the list ordered as in the list.
- func (ll *sLinkedList[V]) Values() []V {
- buf := make([]V, ll.Len())
- i := 0
- el := ll.before
- for el.next != nil {
- el = el.next
- buf[i] = el.value
- i++
- }
- return buf
- }
- 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,
- LessFunc: fn,
- })
- }
|