extern crate alloc;
#[cfg(feature = "std")] use alloc::vec::Vec;
pub fn bubble<T: Ord>(arr: &mut [T]) {
let len = arr.len();
let mut swapped = false;
for i in 0..len {
for j in 0..len - i - 1 {
if arr[j] > arr[j + 1] {
arr.swap(j + 1, j);
swapped = true;
}
}
if !swapped {
break;
}
}
}
pub fn search<T: Ord>(arr: &mut [T]) {
let len = arr.len();
for i in 0..len - 1 {
let mut i_min = i;
for j in i + 1..len {
if arr[j] < arr[i_min] {
i_min = j;
}
}
if i_min != i {
arr.swap(i, i_min);
}
}
}
pub fn insertion<T: Ord + Copy>(arr: &mut [T]) {
for i in 1..arr.len() {
let key = arr[i];
let mut j = i;
let pos = arr[..i].binary_search(&key).unwrap_or_else(|pos| pos);
while j > pos {
arr.swap(j - 1, j);
j -= 1;
}
}
}
#[cfg(feature = "std")]
pub fn merge<T>(slice: &mut [T])
where T: Ord + Clone + Copy + Send + Sync {
let len = slice.len();
if len < 2 {
return;
}
let mid = len / 2;
let (left, right) = slice.split_at_mut(mid);
rayon::join(|| merge(left), || merge(right));
merging(slice);
}
#[cfg(feature = "std")]
fn merging<S, T>(slice: &mut S)
where
S: AsMut<[T]> + AsRef<[T]> + Sync + Send + ?Sized,
T: Ord + Clone + Send + Copy,
{
let len = slice.as_ref().len();
if len < 2 {
return;
}
let mid = len / 2;
let (left, right) = slice.as_ref().split_at(mid);
let mut buffer = Vec::with_capacity(len);
let (mut i, mut j) = (0, 0);
while i < mid && j < len - mid {
if left[i] < right[j] {
buffer.push(left[i]);
i += 1;
} else {
buffer.push(right[j]);
j += 1;
}
}
if i < mid {
buffer.extend_from_slice(&left[i..]);
}
if j < len - mid {
buffer.extend_from_slice(&right[j..]);
}
slice.as_mut().copy_from_slice(&buffer);
}
pub fn cocktail_shaker<T: Ord>(arr: &mut [T]) {
let (mut swapped, mut left, mut right) = (true, 0, arr.len() - 1);
while swapped {
swapped = false;
for i in left..right {
if arr[i] > arr[i + 1] {
arr.swap(i, i + 1);
swapped = true;
}
}
if !swapped {
break;
}
swapped = false;
right -= 1;
for i in (left..right).rev() {
if arr[i] > arr[i + 1] {
arr.swap(i, i + 1);
swapped = true;
}
}
left += 1;
}
}
#[cfg(feature = "std")]
pub fn quick<T>(arr: &mut [T])
where T: Ord + Send + Clone {
if arr.len() <= 1 {
return;
}
let pivot = partition(arr);
let (left, right) = arr.split_at_mut(pivot);
rayon::join(|| quick(left), || quick(right));
}
#[cfg(feature = "std")]
fn partition<T>(arr: &mut [T]) -> usize
where T: Ord + Send + Clone {
let len = arr.len();
let pivot_index = len / 2;
let pivot = arr[pivot_index].clone();
let mut i = 0;
let mut j = len - 1;
loop {
while arr[i] < pivot {
i += 1;
}
while arr[j] > pivot {
j -= 1;
}
if i >= j {
return j;
}
arr.swap(i, j);
}
}