package datastructure import ( "fmt" "reflect" "github.com/duke-git/lancet/v2/datastructure" ) // SinglyLink is a linked list. Whose node has a Value generics and Next pointer points to a next node of the sl. type SinglyLink[T any] struct { Head *datastructure.LinkNode[T] length int } // NewSinglyLink return *SinglyLink instance func NewSinglyLink[T any]() *SinglyLink[T] { return &SinglyLink[T]{Head: nil} } // InsertAtHead insert value into singly linklist at head index func (sl *SinglyLink[T]) InsertAtHead(value T) { newNode := datastructure.NewLinkNode(value) newNode.Next = sl.Head sl.Head = newNode sl.length++ } // InsertAtTail insert value into singly linklist at tail index func (sl *SinglyLink[T]) InsertAtTail(value T) { current := sl.Head if current == nil { sl.InsertAtHead(value) return } for current.Next != nil { current = current.Next } newNode := datastructure.NewLinkNode(value) newNode.Next = nil current.Next = newNode sl.length++ } // InsertAt insert value into singly linklist at index // param `index` should between [0, len(SinglyLink)], if index do not meet the conditions, do nothing func (sl *SinglyLink[T]) InsertAt(index int, value T) { size := sl.length if index < 0 || index > size { return } if index == 0 { sl.InsertAtHead(value) return } if index == size { sl.InsertAtTail(value) return } i := 0 current := sl.Head for current != nil { if i == index-1 { newNode := datastructure.NewLinkNode(value) newNode.Next = current.Next current.Next = newNode sl.length++ return } i++ current = current.Next } return } // DeleteAtHead delete value in singly linklist at head index func (sl *SinglyLink[T]) DeleteAtHead() { if sl.Head == nil { return } current := sl.Head sl.Head = current.Next sl.length-- } // DeleteAtTail delete value in singly linklist at tail func (sl *SinglyLink[T]) DeleteAtTail() { if sl.Head == nil { return } current := sl.Head if current.Next == nil { sl.DeleteAtHead() } for current.Next.Next != nil { current = current.Next } current.Next = nil sl.length-- } // DeleteAt delete value in singly linklist at index // param `index` should be [0, len(SinglyLink)-1] func (sl *SinglyLink[T]) DeleteAt(index int) { if sl.Head == nil { return } current := sl.Head if current.Next == nil || index == 0 { sl.DeleteAtHead() } if index == sl.length-1 { sl.DeleteAtTail() } if index < 0 || index > sl.length-1 { return } i := 0 for current != nil { if i == index-1 { current.Next = current.Next.Next sl.length-- return } i++ current = current.Next } } // DeleteValue delete value in singly linklist func (sl *SinglyLink[T]) DeleteValue(value T) { if sl.Head == nil { return } dummyHead := datastructure.NewLinkNode(value) dummyHead.Next = sl.Head current := dummyHead for current.Next != nil { if reflect.DeepEqual(current.Next.Value, value) { current.Next = current.Next.Next sl.length-- } else { current = current.Next } } sl.Head = dummyHead.Next } // Reverse the linked list func (sl *SinglyLink[T]) Reverse() { var pre, next *datastructure.LinkNode[T] current := sl.Head for current != nil { next = current.Next current.Next = pre pre = current current = next } sl.Head = pre } // GetMiddleNode return node at middle index of linked list func (sl *SinglyLink[T]) GetMiddleNode() *datastructure.LinkNode[T] { if sl.Head == nil { return nil } if sl.Head.Next == nil { return sl.Head } fast := sl.Head slow := sl.Head for fast != nil { fast = fast.Next if fast != nil { fast = fast.Next slow = slow.Next } else { return slow } } return slow } // Size return the count of singly linked list func (sl *SinglyLink[T]) Size() int { return sl.length } // Values return slice of all singly linklist node value func (sl *SinglyLink[T]) Values() []T { result := []T{} current := sl.Head for current != nil { result = append(result, current.Value) current = current.Next } return result } // IsEmpty checks if sl is empty or not func (sl *SinglyLink[T]) IsEmpty() bool { return sl.length == 0 } // Clear all the node in singly linklist func (sl *SinglyLink[T]) Clear() { sl.Head = nil sl.length = 0 } // Print all nodes info of a linked list func (sl *SinglyLink[T]) Print() { current := sl.Head info := "[ " for current != nil { info += fmt.Sprintf("%+v, ", current) current = current.Next } info += " ]" fmt.Println(info) }