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