// InsertionSort performs a simple insertion sort on the sort interface. In the // case of ByDist it performs generally as fast as sort.Sort() except that it // can exploit temporal coherence improving performance dramatically when the // objects have not moved much. func InsertionSort(data sort.Interface) { for i := 0; i < data.Len(); i++ { for j := i; j > 0 && data.Less(j, j-1); j-- { data.Swap(j, j-1) } } }
func insertionSort(a sort.Interface) { for i := 1; i < a.Len(); i++ { for j := i; j > 0 && a.Less(j, j-1); j-- { a.Swap(j-1, j) } } }
func heapSort(a sort.Interface) { helper := HeapHelper{a, a.Len()} heap.Init(&helper) for helper.length > 0 { heap.Pop(&helper) } }
// TimSort sorts the data defined by sort.Interface. func TimSort(a sort.Interface) (err error) { indexes := make([]int, a.Len()) for i := 0; i < len(indexes); i++ { indexes[i] = i } // for i err = Ints(indexes, func(i, j int) bool { return a.Less(i, j) }) if err != nil { return err } // if for i := 0; i < len(indexes); i++ { j := indexes[i] if j == 0 { continue } // if for k := i; j != i; { a.Swap(j, k) k, j, indexes[j] = j, indexes[j], 0 } // for j } // for i return nil }
func Quicksort(sortable sort.Interface) { partition := func(sortable sort.Interface, lo, hi int) int { pivot := hi i := lo for j := lo; j < hi; j++ { if sortable.Less(j, pivot) { sortable.Swap(i, j) i++ } } sortable.Swap(i, hi) return i } var quicksortRecursive func(sortable sort.Interface, lo, hi int) quicksortRecursive = func(sortable sort.Interface, lo, hi int) { if lo < hi { p := partition(sortable, lo, hi) quicksortRecursive(sortable, lo, p-1) quicksortRecursive(sortable, p+1, hi) } } quicksortRecursive(sortable, 0, sortable.Len()-1) }
func Sort(data sort.Interface) { done := make(chan bool) go parallelQuickSort(data, 0, data.Len()-1, done) <-done }
func insertSort(data sort.Interface) { r := data.Len() - 1 for i := 1; i <= r; i++ { for j := i; j > 0 && data.Less(j, j-1); j-- { data.Swap(j, j-1) } } }
// Shuffle sorts data in a randomized order. It uses the default // Source in math/rand, so if clients want to manipulate the outcome, // they should call the appropriate functions in math/rand. // // TODO: Add ability to use custom Sources. func Shuffle(data sort.Interface) { length := data.Len() for i := 0; i < length; i++ { i2 := rand.Intn(i + 1) data.Swap(i, i2) } }
// Insertion sort func Insertion(a sort.Interface) { for i := 2; i < a.Len(); i++ { // insert a[j] into sorted slice a[0:j] for j := i; j > 0 && a.Less(j, j-1); j-- { a.Swap(j, j-1) } } }
func NewWithIndex(sorter sort.Interface) *WithIndex { n := sorter.Len() newToOld := make([]int, n) for i := range newToOld { newToOld[i] = i } return &WithIndex{sorter, newToOld} }
func Insertion(c sort.Interface) { var l = c.Len() for i := 1; i < l; i++ { for j := i; j > 0 && c.Less(j, j-1); j-- { c.Swap(j, j-1) } } }
// Insertion sort func insertionSort(data sort.Interface) { n := data.Len() for i := 1; i < n; i++ { for j := i; j > 0 && data.Less(j, j-1); j-- { data.Swap(j, j-1) } } }
func reverse(seq sort.Interface, firstIndex int) { lastIndex := seq.Len() - 1 numSwap := (lastIndex - firstIndex + 1) / 2 for i := 0; i < numSwap; i++ { seq.Swap(firstIndex+i, lastIndex-i) } }
func IsPalindrome(s sort.Interface) bool { for i, j := 0, s.Len()-1; i < j; i, j = i+1, j-1 { if s.Less(i, j) || s.Less(j, i) { return false } } return true }
// Proposition. For randomly ordered arrays of length N with with distinct keys, // insertion sort uses ~N2/4 compares and ~N2/4 exchanges on the average. // The worst case is ~ N2/2 compares and ~ N2/2 exchanges and the best case is N-1 compares and 0 exchanges. func InsertionSort(a sort.Interface) { n := a.Len() for i := 1; i < n; i++ { for j := i; j > 0 && a.Less(j, j-1); j-- { a.Swap(j, j-1) } } }
// Flip reverses the order of items in a sort.Interface. func Flip(data sort.Interface) { a, b := 0, data.Len()-1 for b > a { data.Swap(a, b) a++ b-- } }
func IsPalindrome(s sort.Interface) bool { for i := 0; i < s.Len()/2; i++ { j := s.Len() - (i + 1) if s.Less(i, j) || s.Less(j, i) { return false } } return true }
func IsPalindrome(s sort.Interface) bool { len := s.Len() for i := 0; i < len/2; i++ { if s.Less(i, len-(i+1)) || s.Less(len-(i+1), i) { return false } } return true }
func IsPalindrome(s sort.Interface) bool { max := s.Len() - 1 for i := 0; i < s.Len()/2; i++ { if !equal(i, max-i, s) { return false } } return true }
// IsUniqued reports whether the elements in data are sorted and unique. func IsUniqued(data sort.Interface) bool { n := data.Len() for i := n - 1; i > 0; i-- { if !data.Less(i-1, i) { return false } } return true }
// "sort" package has "IsSorted" function, but no "IsReversed"; func isReversed(data sort.Interface) bool { n := data.Len() for i := n - 1; i > 0; i-- { if !data.Less(i, i-1) { return false } } return true }
func palindrome(s sort.Interface) bool { last := s.Len() - 1 for i := 0; i < last/2; i++ { if !equals(s, i, last-i) { return false } } return true }
// NewSub opaquely wraps a sub-sequence of the provided sort.Interface. // NewSub(s,i,j) is semantically equivalent to s[i:j], though the underlying // implementation does not need to use a slice. // NewSub will panic unless 0 <= i <= j <= s.Len(). func NewSub(s sort.Interface, i, j int) sort.Interface { if i < 0 || j < i || j > s.Len() { panic(panicmsg) } else if v, ok := s.(sub); ok { // collapse subs of subs return sub{v.s, v.i + i, j - i} } return sub{s, i, j - i} }
// NewProxy sorts comp, duplicating all swaps on each item of data. // NewProxy will panic if any item in data has a different Len() than comp. func NewProxy(comp sort.Interface, data ...sort.Interface) sort.Interface { l := comp.Len() for _, d := range data { if l != d.Len() { panic(panicmsg) } } return proxy{comp, data} }
// Sort sorts data. // It makes one call to data.Len to determine n, and O(n*log(n)) calls to // data.Less and data.Swap. The sort is not guaranteed to be stable. func Sort(data sort.Interface) { // Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached. n := data.Len() maxDepth := 0 for i := n; i > 0; i >>= 1 { maxDepth++ } maxDepth *= 2 quickSort(data, 0, n, maxDepth, nil) }
// Quicksort performs a parallel quicksort on data. func Quicksort(data sort.Interface) { a, b := 0, data.Len() n := b - a maxDepth := 0 for i := n; i > 0; i >>= 1 { maxDepth++ } maxDepth *= 2 parallelSort(data, quickSortWorker, task{-maxDepth - 1, a, b}) }
func Heapsort(data sort.Interface) sort.Interface { buildMaxHeap(data) heapsize := data.Len() for i := data.Len() - 1; i > 0; i-- { data.Swap(0, i) heapsize-- maxHeapify(data, 0, heapsize) } return data }
// InsertionSort sorts given data and has next properties: // // - Stable // - O(1) extra space // - O(n*n) comparisons and swaps // - Adaptive: O(n) time when nearly sorted // - Very low overhead // func InsertionSort(data sort.Interface) { // Loop invariant: at the start of each iteration, the data[0:i] consist // of the elements originally in data[0:i], but in sorted order. for i := 1; i < data.Len(); i++ { // Loop invariant: data[k:i] will have the smallest element on position k. for k := i; k > 0 && data.Less(k, k-1); k-- { data.Swap(k, k-1) } } }
func isPalindrome(s sort.Interface) bool { maxIndex := s.Len() - 1 for i := 0; i < maxIndex/2; i++ { if !s.Less(i, maxIndex-i) && !s.Less(maxIndex-i, i) { continue } return false } return true }
// BubbleSort implementation func Bubble(a sort.Interface) { for i := 0; i < a.Len(); i++ { for j := a.Len() - 1; j > i; j-- { if a.Less(j, j-1) { a.Swap(j, j-1) } } } }