-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
cycle.jule
54 lines (51 loc) · 1.48 KB
/
cycle.jule
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
// 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.
fn Cycle[T: numeric](mut arr: []T): []T {
mut counter, mut cycle, len := 0, 0, len(arr)
// Early return if the array too small
if len <= 1 {
ret arr
}
for cycle < len-1; cycle++ {
mut elem := arr[cycle]
// Find total smaller elements to right
mut pos := cycle
counter = cycle + 1
for 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
counter = cycle + 1
for 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]
}
}
}
ret arr
}