diff --git a/src/data_structures/queue.rs b/src/data_structures/queue.rs index 5c75891..672d7cb 100644 --- a/src/data_structures/queue.rs +++ b/src/data_structures/queue.rs @@ -1,24 +1,32 @@ +use std::collections::VecDeque; + +#[derive(Debug)] pub struct Queue { - queue: Vec, + queue: VecDeque, } impl Queue { pub fn new() -> Self { - Queue { queue: Vec::new() } + Queue { queue: VecDeque::new() } } + pub fn length(&self) -> usize { self.queue.len() } + pub fn enqueue(&mut self, item: T) { - self.queue.push(item) + self.queue.push_back(item); } - pub fn dequeue(&mut self) -> T { - self.queue.remove(0) + + pub fn dequeue(&mut self) -> Option { + self.queue.pop_front() } + pub fn is_empty(&self) -> bool { self.queue.is_empty() } + pub fn peek(&self) -> Option<&T> { - self.queue.first() + self.queue.front() } } diff --git a/src/main.rs b/src/main.rs index 769c973..aceec52 100644 --- a/src/main.rs +++ b/src/main.rs @@ -71,14 +71,14 @@ fn merge_sort_demo(){ println!("Array before merge sort: {:?}",arr); println!("Array after merge sort: {:?}",merge_sort::merge_sort(arr)); } -// fn radix_sort_demo(){ -// println!("-------------------"); -// println!("RADIX SORT DEMO:"); -// println!("-------------------"); -// let arr = &[9, 3, 7, 4, 69, 420, 42]; -// println!("Array before radix sort: {:?}",arr); -// println!("Array after radix sort: {:?}",radix_sort::radix_sort(arr)); -// } +fn radix_sort_demo(){ + println!("-------------------"); + println!("RADIX SORT DEMO:"); + println!("-------------------"); + let arr = vec![9, 3, 7, 4, 69, 420, 42]; + println!("Array before radix sort: {:?}",arr); + println!("Array after radix sort: {:?}",radix_sort::radix_sort(arr)); +} fn main() { println!(""); println!("|~~~~~~~~~~~~~~~|"); diff --git a/src/radix_sort.rs b/src/radix_sort.rs index 7634357..1a1b888 100644 --- a/src/radix_sort.rs +++ b/src/radix_sort.rs @@ -1,46 +1,153 @@ -// use crate::data_structures::stack::Stack; -// pub fn radix_sort(arr: &[u64]) -> Vec { -// let mut buckets: [Stack; 10] = [ -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// Stack::new(), -// ]; -// let mut sort_vec = arr.to_vec(); -// let largest_place_value = get_largest_place(arr); +use crate::data_structures::queue::Queue; +/// Represents a bucket containing a value and a queue of unsigned 64-bit integers. +#[derive(Debug)] +struct Bucket { + value: u8, + queue: Queue, +} -// for counter in 0..largest_place_value { -// for num in &sort_vec { -// let digit = get_digit(*num, counter as usize); -// buckets[digit].push(*num); -// } +impl Bucket { + /// Creates a new Bucket instance with initial value 0 and an empty queue. + fn new() -> Self { + Bucket { + value: 0, + queue: Queue::new(), + } + } +} -// let mut index = 0; -// for stack in &mut buckets { -// while let Some(value) = stack.pop() { -// sort_vec[index] = value; -// index += 1; -// } -// } -// } +/// Represents a collection of buckets. +#[derive(Debug)] +struct Buckets { + buckets: Vec, +} -// sort_vec -// } +impl Buckets { + /// Creates a new Buckets instance with 10 empty buckets. + fn new() -> Self { + let mut buckets = Vec::with_capacity(10); + for i in 0..10 { + buckets.push(Bucket {value: i as u8, queue: Queue::new()}); + } + Buckets { buckets } + } -// fn get_digit(num: u64, place: usize) -> usize { -// (num / 10u64.pow(place as u32)) as usize % 10 -// } + /// Enqueues an item into the bucket at the specified index. + /// + /// # Panics + /// Panics if the specified bucket index is out of range. + fn enqueue(&mut self, bucket_index: usize, item: u64) { + if let Some(bucket) = self.buckets.get_mut(bucket_index) { + bucket.queue.enqueue(item); + } else { + panic!("Invalid bucket index"); + } + } + + /// Dequeues an item from the bucket at the specified index. + /// + /// # Panics + /// Panics if the specified bucket index is out of range. + fn dequeue(&mut self, bucket_index: usize) -> Option { + if let Some(bucket) = self.buckets.get_mut(bucket_index) { + bucket.queue.dequeue() + } else { + panic!("Invalid bucket index"); + } + } + + /// Checks if the bucket at the specified index is empty. + /// + /// # Panics + /// Panics if the specified bucket index is out of range. + fn is_empty(&self, bucket_index: usize) -> bool { + if let Some(bucket) = self.buckets.get(bucket_index) { + bucket.queue.is_empty() + } else { + panic!("Invalid bucket index"); + } + } + + /// Retrieves a reference to the front item of the bucket at the specified index. + /// + /// # Panics + /// Panics if the specified bucket index is out of range. + fn peek(&self, bucket_index: usize) -> Option<&u64> { + if let Some(bucket) = self.buckets.get(bucket_index) { + bucket.queue.peek() + } else { + panic!("Invalid bucket index"); + } + } +} + +/// Sorts a vector of unsigned 64-bit integers using radix sort algorithm. +pub fn radix_sort(arr: Vec) -> Vec{ + let largest_unit = get_largest_place(arr.clone()); + let mut counter = 0; + let mut buckets = Buckets::new(); + let mut sort_vec: Vec = arr.clone(); + while counter <= largest_unit { + for i in sort_vec.clone() { + let sort_value = get_value_at_unit(i, counter); + match sort_value { + 0 => buckets.enqueue(0, i), + 1 => buckets.enqueue(1, i), + 2 => buckets.enqueue(2, i), + 3 => buckets.enqueue(3, i), + 4 => buckets.enqueue(4, i), + 5 => buckets.enqueue(5, i), + 6 => buckets.enqueue(6, i), + 7 => buckets.enqueue(7, i), + 8 => buckets.enqueue(8, i), + 9 => buckets.enqueue(9, i), + _ => buckets.enqueue(0, i), + } + }; + sort_vec.clear(); + for j in 0..buckets.buckets.len() { + while let Some(value) = buckets.dequeue(j) { + sort_vec.push(value); + } + } + counter += 1; + } + return sort_vec; +} -// fn get_largest_place(arr: &[u64]) -> usize { -// arr.iter() -// .map(|&num| (num as f64).log(10.0).ceil() as usize) -// .max() -// .unwrap_or(0) -// } +/// Retrieves the digit at the specified place from a given number. +fn get_value_at_unit(num: u64, place: u64) -> u64 { + (num / 10u64.pow(place as u32)) % 10 +} + +/// Calculates the largest place value among a vector of unsigned 64-bit integers. +fn get_largest_place(arr: Vec) -> u64 { + arr.iter().map(|&num| (num as f64).log(10.0).ceil() as u64).max().unwrap_or(0) +} + +/// Validates if a vector of unsigned 64-bit integers is sorted in ascending order. +/// +/// # Arguments +/// +/// * `arr` - A vector of unsigned 64-bit integers. +/// +/// # Returns +/// +/// * `Result<(), &'static str>` - `Ok(())` if the vector is sorted, otherwise `Err("The vector is not sorted")`. +fn validate_sort(arr: Vec) -> Result<(), &'static str> { + // Check if the vector is empty + if arr.is_empty() { + return Ok(()); + } + + // Iterate through the vector and check if each element is less than or equal to the next one + for i in 0..arr.len() - 1 { + if arr[i] > arr[i + 1] { + return Err("The vector is not sorted"); + } + } + + // If all elements are in sorted order, return Ok(()) + Ok(()) +}