github.com/djordje200179/extendedlibrary/datastructures@v1.7.1-0.20240227175559-d09520a92dd4/cols/linklist/sorting.go (about) 1 package linklist 2 3 import ( 4 "github.com/djordje200179/extendedlibrary/misc/functions/comparison" 5 ) 6 7 // Sort sorts the elements in the List by the specified comparator. 8 // The sorting algorithm is a stable variant of merge sort. 9 func (list *List[T]) Sort(comparator comparison.Comparator[T]) { 10 if list == nil || list.head == nil || list.head.next == nil { 11 return 12 } 13 14 firstList, secondList := splitList(list) 15 16 firstList.Sort(comparator) 17 secondList.Sort(comparator) 18 19 sortedMerge(firstList, secondList, list, comparator) 20 } 21 22 func sortedMerge[T any](firstList, secondList, resultList *List[T], comparator comparison.Comparator[T]) { 23 if firstList == nil { 24 *resultList = *secondList 25 } 26 27 if secondList == nil { 28 *resultList = *firstList 29 } 30 31 resultList.Clear() 32 33 firstListCurr := firstList.head 34 secondListCurr := secondList.head 35 36 for firstListCurr != nil && secondListCurr != nil { 37 if comparator(firstListCurr.Value, secondListCurr.Value) == comparison.FirstSmaller { 38 resultList.Append(firstListCurr.Value) 39 firstListCurr = firstListCurr.next 40 } else { 41 resultList.Append(secondListCurr.Value) 42 secondListCurr = secondListCurr.next 43 } 44 } 45 46 for firstListCurr != nil { 47 resultList.Append(firstListCurr.Value) 48 firstListCurr = firstListCurr.next 49 } 50 51 for secondListCurr != nil { 52 resultList.Append(secondListCurr.Value) 53 secondListCurr = secondListCurr.next 54 } 55 } 56 57 func splitList[T any](list *List[T]) (*List[T], *List[T]) { 58 middleIndex := list.Size() / 2 59 middleNode := list.GetNode(middleIndex - 1) 60 61 firstList := &List[T]{ 62 head: list.head, 63 tail: middleNode, 64 size: middleIndex, 65 } 66 67 secondList := &List[T]{ 68 head: middleNode.next, 69 tail: list.tail, 70 size: list.Size() - middleIndex, 71 } 72 73 middleNode.next.prev = nil 74 middleNode.next = nil 75 76 list.Clear() 77 78 return firstList, secondList 79 }