|
| 1 | +pub fn comp_and_swap<T: Ord>(array: &mut [T], index1: i32, index2: i32, direction: i32) { |
| 2 | + if (direction == 1 && array[index1 as usize] > array[index2 as usize]) |
| 3 | + || (direction == 0 && array[index1 as usize] < array[index2 as usize]) |
| 4 | + { |
| 5 | + array.swap(index1 as usize, index2 as usize); |
| 6 | + } |
| 7 | +} |
| 8 | + |
| 9 | +pub fn bitonic_merge<T: Ord>(array: &mut [T], low: i32, length: i32, direction: i32) { |
| 10 | + if length > 1 { |
| 11 | + let middle = length / 2; |
| 12 | + for i in low..(low + middle) { |
| 13 | + comp_and_swap(array, i, i + middle, direction); |
| 14 | + } |
| 15 | + bitonic_merge(array, low, middle, direction); |
| 16 | + bitonic_merge(array, low + middle, middle, direction); |
| 17 | + } |
| 18 | +} |
| 19 | + |
| 20 | +pub fn bitonic_sort<T: Ord>(array: &mut [T], low: i32, length: i32, direction: i32) { |
| 21 | + if length > 1 { |
| 22 | + let middle = length / 2; |
| 23 | + bitonic_sort(array, low, middle, 1); |
| 24 | + bitonic_sort(array, low + middle, middle, 0); |
| 25 | + bitonic_merge(array, low, length, direction); |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | +//Note that this program works only when size of input is a power of 2. |
| 30 | +#[cfg(test)] |
| 31 | +mod tests { |
| 32 | + use super::*; |
| 33 | + |
| 34 | + #[test] |
| 35 | + fn descending() { |
| 36 | + //descending |
| 37 | + let mut ve1 = vec![6, 5, 4, 3]; |
| 38 | + bitonic_sort(&mut ve1, 0, 4, 1); |
| 39 | + for i in 0..ve1.len() - 1 { |
| 40 | + assert!(ve1[i] <= ve1[i + 1]); |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + #[test] |
| 45 | + fn ascending() { |
| 46 | + //pre-sorted |
| 47 | + let mut ve2 = vec![1, 2, 3, 4]; |
| 48 | + bitonic_sort(&mut ve2, 0, 4, 0); |
| 49 | + for i in 0..ve2.len() - 1 { |
| 50 | + assert!(ve2[i] >= ve2[i + 1]); |
| 51 | + } |
| 52 | + } |
| 53 | +} |
0 commit comments