forked from TheAlgorithms/Go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cyclesort.go
58 lines (53 loc) · 1.56 KB
/
cyclesort.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package sort
import (
"github.com/TheAlgorithms/Go/constraints"
)
// Cycle sort is an in-place, unstable sorting algorithm that is particularly useful
// when sorting arrays containing elements with a small range of values. It is theoretically
// optimal in terms of the total number of writes to the original array.
func Cycle[T constraints.Number](arr []T) []T {
counter, cycle, len := 0, 0, len(arr)
// Early return if the array too small
if len <= 1 {
return arr
}
for cycle = 0; cycle < len-1; cycle++ {
elem := arr[cycle]
// Find total smaller elements to right
pos := cycle
for counter = cycle + 1; counter < len; counter++ {
if arr[counter] < elem {
pos++
}
}
// In case this element is already in correct position, let's skip processing
if pos == cycle {
continue
}
// In case we have same elements, we want to skip to the end of that list as well, ignoring order
// This makes the algorithm unstable for composite elements
for elem == arr[pos] {
pos++
}
// Now let us put the item to it's right position
arr[pos], elem = elem, arr[pos]
//We need to rotate the array till we have reached the start of the cycle again
for pos != cycle {
pos = cycle
// Find smaller elements to right again
for counter = cycle + 1; counter < len; counter++ {
if arr[counter] < elem {
pos++
}
}
for elem == arr[pos] {
pos++
}
//We can do this unconditionally, but the check helps prevent redundant writes to the array
if elem != arr[pos] {
arr[pos], elem = elem, arr[pos]
}
}
}
return arr
}