7
7
/// This sorting algorithm transforms the input array into implicit heap data
8
8
/// structure and then produces the sorted array by repeatedly extracting the
9
9
/// largest remaining element
10
+ /// This algorithm makes use of Leonardo numbers. It's a sequence of numbers
11
+ /// defined by:
12
+ /// ```no_run
13
+ /// L(0) = 1
14
+ /// L(1) = 1
15
+ /// L(n) = L(n - 1) + L(n - 2) + 1
16
+ /// *OR*
17
+ /// L(n) = 2 * Fib(n + 1) - 1
18
+ /// ```
19
+ /// Where *+ 1* is "add" number and "Fib" are Fibonacci numbers
20
+ ///
21
+ /// For 64-bit systems it's possible to use 90 Leonardo numbers placed as a
22
+ /// constant array [usize; 90]
10
23
///
11
24
/// # Examples
12
25
/// ```rust
19
32
/// sorting_rs::smooth_sort(&mut strings);
20
33
/// assert_eq!(strings, &["cargo", "rustc", "rustup"]);
21
34
/// ```
35
+ use std:: fmt:: Debug ;
22
36
23
- pub fn smooth_sort < T : PartialOrd > ( input : & mut [ T ] ) {
37
+ const LEO_NUMS : [ usize ; 90 ] = [
38
+ 1 , 1 , 3 , 5 , 9 , 15 , 25 , 41 , 67 , 109 , 177 , 287 , 465 , 753 , 1219 , 1973 , 3193 ,
39
+ 5167 , 8361 , 13529 , 21891 , 35421 , 57313 , 92735 , 150049 , 242785 , 392835 ,
40
+ 635621 , 1028457 , 1664079 , 2692537 , 4356617 , 7049155 , 11405773 , 18454929 ,
41
+ 29860703 , 48315633 , 78176337 , 126491971 , 204668309 , 331160281 , 535828591 ,
42
+ 866988873 , 1402817465 , 2269806339 , 3672623805 , 5942430145 , 9615053951 ,
43
+ 15557484097 , 25172538049 , 40730022147 , 65902560197 , 106632582345 ,
44
+ 172535142543 , 279167724889 , 451702867433 , 730870592323 , 1182573459757 ,
45
+ 1913444052081 , 3096017511839 , 5009461563921 , 8105479075761 ,
46
+ 13114940639683 , 21220419715445 , 34335360355129 , 55555780070575 ,
47
+ 89891140425705 , 145446920496281 , 235338060921987 , 380784981418269 ,
48
+ 616123042340257 , 996908023758527 , 1613031066098785 , 2609939089857313 ,
49
+ 4222970155956099 , 6832909245813413 , 11055879401769513 , 17888788647582927 ,
50
+ 28944668049352441 , 46833456696935369 , 75778124746287811 , 122611581443223181 ,
51
+ 198389706189510993 , 321001287632734175 , 519390993822245169 ,
52
+ 840392281454979345 , 1359783275277224515 , 2200175556732203861 ,
53
+ 3559958832009428377 , 5760134388741632239 ,
54
+ ] ;
55
+
56
+ pub fn smooth_sort < T : PartialOrd + Debug > ( input : & mut [ T ] )
57
+ {
24
58
if input. len ( ) < 2 { return ; }
25
59
26
- unimplemented ! ( "Not yet ready!" ) ;
60
+ // Init addtitional heap
61
+ let input = input;
62
+ let in_len = input. len ( ) ;
63
+ let mut heap = Vec :: < usize > :: new ( ) ;
64
+
65
+ for i in 0 ..in_len {
66
+ if heap. len ( ) >= 2 && heap[ heap. len ( ) - 2 ] == heap[ heap. len ( ) - 1 ] + 1 {
67
+ heap. pop ( ) ;
68
+ let len_leo = heap. len ( ) ;
69
+ heap[ len_leo - 1 ] += 1 ;
70
+ } else {
71
+ if heap. len ( ) >= 1 && heap[ heap. len ( ) - 1 ] == 1 {
72
+ heap. push ( 0 ) ;
73
+ } else {
74
+ heap. push ( 1 ) ;
75
+ }
76
+ }
77
+ restore_heap ( input, i, & heap) ;
78
+ }
79
+ println ! ( "DEBUG: {:?}" , input) ;
80
+
81
+ for i in ( 0 ..in_len) . rev ( ) {
82
+ if heap[ heap. len ( ) - 1 ] < 2 {
83
+ heap. pop ( ) ;
84
+ } else {
85
+ let k = heap. pop ( ) . unwrap ( ) ;
86
+ let t = get_child_trees ( i, k) ;
87
+ // tr kr tl kl
88
+ // 0 1 2 3
89
+ heap. push ( t[ 3 ] ) ;
90
+ restore_heap ( input, t[ 2 ] , & heap) ;
91
+ heap. push ( t[ 1 ] ) ;
92
+ restore_heap ( input, t[ 0 ] , & heap) ;
93
+ }
94
+ }
95
+ println ! ( "DEBUG: {:?}" , input) ;
96
+ }
97
+
98
+ fn restore_heap < T : PartialOrd > ( input : & mut [ T ] , index : usize , heap : & Vec < usize > )
99
+ {
100
+ // Insertion sorting
101
+ let mut current = heap. len ( ) - 1 ;
102
+ let mut i = index;
103
+ let mut k = heap[ current] ;
104
+
105
+ while current > 0 {
106
+ let j = i - LEO_NUMS [ k] ;
107
+ if input[ j] > input[ i] && ( k < 2 || input[ j] > input[ i - 1 ] &&
108
+ input[ j] > input[ i - 2 ] ) {
109
+ input. swap ( i, j) ;
110
+ i = j;
111
+ current -= 1 ;
112
+ k = heap[ current] ;
113
+ } else {
114
+ break ;
115
+ }
116
+ }
117
+ while k > 2 {
118
+ let t = get_child_trees ( i, k) ;
119
+ // tr kr tl kl
120
+ // 0 1 2 3
121
+ if input[ i] < input[ t[ 0 ] ] || input[ i] < input[ t[ 2 ] ] {
122
+ if input[ t[ 0 ] ] > input[ t[ 2 ] ] {
123
+ input. swap ( i, t[ 0 ] ) ;
124
+ i = t[ 0 ] ;
125
+ k = t[ 1 ] ;
126
+ } else {
127
+ input. swap ( i, t[ 2 ] ) ;
128
+ i = t[ 2 ] ;
129
+ k = t[ 3 ] ;
130
+ }
131
+ } else {
132
+ break ;
133
+ }
134
+ }
135
+ }
136
+
137
+ fn get_child_trees ( i : usize , k : usize ) -> [ usize ; 4 ] {
138
+ let tr = i - 1 ;
139
+ let kr = k - 2 ;
140
+ let tl = tr - LEO_NUMS [ kr] ;
141
+ let kl = k - 1 ;
142
+ [ tr, kr, tl, kl]
27
143
}
28
144
29
145
#[ cfg( test) ]
30
146
mod tests {
31
147
use super :: * ;
32
148
33
149
#[ test]
34
- fn test_slow ( ) {
35
- let mut vector_in = vec ! [ 10 , 20 , 11 , 24 ] ;
150
+ fn test_smooth ( ) {
151
+ let mut vector_in = vec ! [ 20 , 10 , 11 , 13 ] ;
36
152
smooth_sort ( & mut vector_in) ;
37
- debug_assert_eq ! ( vector_in, vec! [ 10 , 11 , 20 , 24 ] ) ;
153
+ debug_assert_eq ! ( vector_in, & [ 10 , 11 , 13 , 20 ] ) ;
38
154
}
39
155
#[ test]
40
- fn test_slow_empty ( ) {
156
+ fn test_smooth_empty ( ) {
41
157
let mut vector_in: Vec < i32 > = vec ! [ ] ;
42
158
smooth_sort ( & mut vector_in) ;
43
159
debug_assert_eq ! ( vector_in, & [ ] ) ;
44
160
}
45
161
#[ test]
46
- fn test_slow_len1 ( ) {
162
+ fn test_smooth_len1 ( ) {
47
163
let mut vector_in = vec ! [ 1 ] ;
48
164
smooth_sort ( & mut vector_in) ;
49
- debug_assert_eq ! ( vector_in, vec! [ 1 ] ) ;
165
+ debug_assert_eq ! ( vector_in, & [ 1 ] ) ;
50
166
}
51
167
}
0 commit comments