1
+ /// Sorts a slice in-place using
2
+ /// [Bitonic sort](https://en.wikipedia.org/wiki/Bitonic_sorter).
3
+ /// All kinds of slices can be sorted as long as they implement
4
+ /// [`PartialOrd`](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html).
5
+ ///
6
+ /// Bitonic sort is one of the fastest sorting networks. Sorting network has the
7
+ /// sequence of comparisons that are not data-dependent.
8
+ ///
9
+ /// # Examples
10
+ /// ```rust
11
+ /// let mut vec = vec![5,3,2,4];
12
+ /// sorting_rs::bitonic_sort(&mut vec);
13
+ /// assert_eq!(vec, &[2,3,4,5]);
14
+ /// ```
15
+ /// ```rust
16
+ /// let mut strings = vec!["rustc", "cargo", "rustup"];
17
+ /// sorting_rs::bitonic_sort(&mut strings);
18
+ /// assert_eq!(strings, &["cargo", "rustc", "rustup"]);
19
+ /// ```
20
+ // use std::fmt::Debug;
21
+
22
+ pub fn bitonic_sort < T : PartialOrd + Max < T > > ( input : & mut [ T ] ) {
23
+ if input. len ( ) < 2 { return ; }
24
+
25
+ let in_len = input. len ( ) ;
26
+ // Convert to vec of options
27
+ // let mut input_m: Vec<Option<&T>> = input.into_iter().map(Some).collect();
28
+ // Check if input array has length of power of 2 and add None to fill it up
29
+ let mut add_len = 0 ;
30
+ println ! ( "{}" , add_len) ;
31
+
32
+ for ( i, num) in POWERS_OF_TWO . into_iter ( ) . enumerate ( ) {
33
+ if in_len == * num { add_len = 0 ; }
34
+ if i > 0 {
35
+ if in_len < * num { if in_len > POWERS_OF_TWO [ i - 1 ] {
36
+ add_len = num - in_len; }
37
+ }
38
+ }
39
+ }
40
+
41
+ if add_len > 0 { input. append ( vec ! [ T :: MAX ; add_len] ) ; }
42
+
43
+ sort ( & mut input, true ) ;
44
+
45
+ }
46
+
47
+
48
+ // pub fn sort<T: PartialOrd>(input: &mut [T], mode: bool) {
49
+ // if input.len() > 1 {
50
+ // let mid_point = input.len() / 2;
51
+ // sort(&mut input[..mid_point], true);
52
+ // sort(&mut input[mid_point..], false);
53
+ // sub_sort(input, mode);
54
+ // }
55
+ // }
56
+ // fn sub_sort<T: PartialOrd>(input: &mut [T], mode: bool) {
57
+ // if input.len() > 1 {
58
+ // compare_and_swap(input, mode);
59
+ // let mid_point = input.len() / 2;
60
+ // sub_sort(&mut input[..mid_point], mode);
61
+ // sub_sort(&mut input[mid_point..], mode);
62
+ // }
63
+ // }
64
+ // fn compare_and_swap<T: PartialOrd>(input: &mut [T], mode: bool) {
65
+ // let mid_point = input.len() / 2;
66
+ // for i in 0..mid_point {
67
+ // if input[i].is_none() || input[i + 1].is_none() {break;}
68
+ // else if (input[i] > input[mid_point + i]) == mode {
69
+ // input.swap(i, mid_point + i);
70
+ // }
71
+ // }
72
+ // }
73
+
74
+ // fn bit_comp<T: PartialOrd>(input: &mut Vec<T>, mode: bool) {
75
+ // let d = input.len() / 2;
76
+ // for i in 0..d {
77
+ // if (input[i] > input[i + d]) == mode {
78
+ // input.swap(i, i + d);
79
+ // }
80
+ // }
81
+ // }
82
+
83
+ /// usize for 64 bit is limited with 63 numbers
84
+ const POWERS_OF_TWO : [ usize ; 63 ] = [ 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 ,
85
+ 2048 , 4096 , 8192 , 16384 , 32768 , 65536 , 131072 , 262144 , 524288 , 1048576 ,
86
+ 2097152 , 4194304 , 8388608 , 16777216 , 33554432 , 67108864 , 134217728 , 268435456 ,
87
+ 536870912 , 1073741824 , 2147483648 , 4294967296 , 8589934592 , 17179869184 ,
88
+ 34359738368 , 68719476736 , 137438953472 , 274877906944 , 549755813888 ,
89
+ 1099511627776 , 2199023255552 , 4398046511104 , 8796093022208 , 17592186044416 ,
90
+ 35184372088832 , 70368744177664 , 140737488355328 , 281474976710656 ,
91
+ 562949953421312 , 1125899906842624 , 2251799813685248 , 4503599627370496 ,
92
+ 9007199254740992 , 18014398509481984 , 36028797018963968 , 72057594037927936 ,
93
+ 144115188075855872 , 288230376151711744 , 576460752303423488 , 1152921504606846976 ,
94
+ 2305843009213693952 , 4611686018427387904 , 9223372036854775808 ] ;
95
+
96
+ /// Implemented Max values for generics to use in the code
97
+ macro_rules! impl_max {
98
+ ( $( $t: ty) * ) => ( $(
99
+ impl Max for $t {
100
+ #[ inline]
101
+ fn get_max( & self ) -> Self { * self :: MAX }
102
+ }
103
+ ) * )
104
+ }
105
+ pub trait Max < T : PartialOrd > { fn get_max ( & self ) -> Self ; }
106
+ // impl Max<T> for T {fn get_max(&self) -> T {T::MAX}}
107
+ // impl Max<u8> for u8 {fn get_max(&self) -> u8 {u8::MAX}}
108
+ impl_max ! {
109
+ bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
110
+ }
111
+
112
+
113
+ // fn bit_sort<T: PartialOrd>(input: &mut Vec<T>, mode: bool) {
114
+ // if input.len() < 2 {return;}
115
+
116
+ // let mut left: Vec<T> = input.drain(..input.len() / 2).collect();
117
+ // bit_sort(&mut left, true);
118
+ // bit_sort(input, false);
119
+ // left.append(input);
120
+ // bit_merge(&mut left, mode);
121
+ // std::mem::swap(input, &mut left);
122
+ // }
123
+
124
+ // fn bit_merge<T: PartialOrd>(input: &mut Vec<T>, mode) {
125
+ // if input.len() == 1 {return;}
126
+ // else {
127
+ // bit_comp(input, mode);
128
+ // let mut left: Vec<T> = input.drain(..input.len() / 2).collect();
129
+ // bit_merge(mode, &mut left);
130
+ // bit_merge(mode, input);
131
+ // left.append(input);
132
+ // std::mem::swap(input, &mut left);
133
+ // }
134
+ // }
135
+
136
+ #[ cfg( test) ]
137
+ mod tests {
138
+ use super :: * ;
139
+
140
+ #[ test]
141
+ fn test_bitonic ( ) {
142
+ let mut vector_in = vec ! [ 10 , 20 , 11 , 24 , 15 ] ;
143
+ bitonic_sort ( & mut vector_in) ;
144
+ debug_assert_eq ! ( vector_in, vec![ 10 , 11 , 15 , 20 , 24 ] ) ;
145
+ }
146
+ #[ test]
147
+ fn test_bitonic_empty ( ) {
148
+ let mut vector_in: Vec < u8 > = vec ! [ ] ;
149
+ bitonic_sort ( & mut vector_in) ;
150
+ debug_assert_eq ! ( vector_in, vec![ ] ) ;
151
+ }
152
+ #[ test]
153
+ fn test_bitonic_len1 ( ) {
154
+ let mut vector_in = vec ! [ 1 ] ;
155
+ bitonic_sort ( & mut vector_in) ;
156
+ debug_assert_eq ! ( vector_in, vec![ 1 ] ) ;
157
+ }
158
+ #[ test]
159
+ fn test_u8_max ( ) {
160
+
161
+ let mut input = 12 ;
162
+ input = input. get_max ( ) ;
163
+ debug_assert_eq ! ( input, u8 :: MAX ) ;
164
+ }
165
+ }
0 commit comments