Split the sorters in separated modules and added merge sort
parent
5dbaef1dec
commit
f9fc7068fc
|
@ -0,0 +1,16 @@
|
|||
use crate::{SortMessage, SortVisualizer};
|
||||
|
||||
pub fn sort(vis: &mut SortVisualizer) {
|
||||
let n = vis.arr.len();
|
||||
|
||||
for i in 0..n {
|
||||
for j in 0..n - i - 1 {
|
||||
if vis.arr[j] > vis.arr[j + 1] {
|
||||
vis.arr.swap(j, j + 1);
|
||||
vis.tx.send(SortMessage::Data(vis.arr.clone())).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vis.tx.send(SortMessage::Done).unwrap();
|
||||
}
|
104
src/main.rs
104
src/main.rs
|
@ -13,22 +13,32 @@ use fltk::{
|
|||
use fltk_theme::{color_themes, ColorTheme};
|
||||
use rand::Rng;
|
||||
|
||||
const SIZE: u32 = 50;
|
||||
mod bubble;
|
||||
mod merge;
|
||||
mod quick;
|
||||
|
||||
const SIZE: u32 = 100;
|
||||
const MAX_VALUE: f64 = 100.0;
|
||||
|
||||
type Sorter = fn(&mut SortVisualizer);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SortVisualizer {
|
||||
arr: Vec<f64>,
|
||||
chart: Chart,
|
||||
sorter: Sorter,
|
||||
tx: Sender<Vec<f64>>,
|
||||
rx: Receiver<Vec<f64>>,
|
||||
enum SortMessage {
|
||||
Data(Vec<f64>),
|
||||
Done,
|
||||
}
|
||||
|
||||
impl SortVisualizer {
|
||||
fn new(id: usize, arr: Vec<f64>, sorter: Sorter) -> Self {
|
||||
#[derive(Debug)]
|
||||
struct SortVisualizer<'a> {
|
||||
arr: Vec<f64>,
|
||||
name: &'a str,
|
||||
chart: Chart,
|
||||
sorter: Sorter,
|
||||
tx: Sender<SortMessage>,
|
||||
rx: Receiver<SortMessage>,
|
||||
}
|
||||
|
||||
impl<'a> SortVisualizer<'a> {
|
||||
fn new(id: usize, name: &'a str, arr: Vec<f64>, sorter: Sorter) -> Self {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let y = 300 * (id) as i32;
|
||||
|
||||
|
@ -37,9 +47,11 @@ impl SortVisualizer {
|
|||
chart.set_size(500, 250);
|
||||
chart.set_frame(FrameType::FlatBox);
|
||||
chart.set_bounds(0.0, MAX_VALUE);
|
||||
chart.set_label(name);
|
||||
|
||||
Self {
|
||||
arr,
|
||||
name,
|
||||
chart,
|
||||
sorter,
|
||||
tx,
|
||||
|
@ -57,54 +69,10 @@ impl SortVisualizer {
|
|||
self.chart.add(*i, "", Color::Cyan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn quick_sort(vis: &mut SortVisualizer) {
|
||||
let n = vis.arr.len();
|
||||
let low = 0;
|
||||
let high = n - 1;
|
||||
|
||||
quick_sorting(vis, low, high);
|
||||
}
|
||||
|
||||
fn quick_sorting(vis: &mut SortVisualizer, low: usize, high: usize) {
|
||||
if low < high {
|
||||
let pivot = partition(vis, low, high);
|
||||
if pivot > 0 {
|
||||
quick_sorting(vis, low, pivot - 1);
|
||||
}
|
||||
quick_sorting(vis, pivot + 1, high);
|
||||
}
|
||||
}
|
||||
|
||||
fn partition(vis: &mut SortVisualizer, low: usize, high: usize) -> usize {
|
||||
let pivot = high;
|
||||
let mut i = low as isize - 1;
|
||||
|
||||
for j in low..high {
|
||||
if vis.arr[j] < vis.arr[pivot] {
|
||||
i += 1;
|
||||
vis.arr.swap(i as usize, j);
|
||||
vis.tx.send(vis.arr.clone()).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
vis.arr.swap((i + 1) as usize, pivot);
|
||||
vis.tx.send(vis.arr.clone()).unwrap();
|
||||
|
||||
(i + 1) as usize
|
||||
}
|
||||
|
||||
fn bubble_sort(vis: &mut SortVisualizer) {
|
||||
let n = vis.arr.len();
|
||||
|
||||
for i in 0..n {
|
||||
for j in 0..n - i - 1 {
|
||||
if vis.arr[j] > vis.arr[j + 1] {
|
||||
vis.arr.swap(j, j + 1);
|
||||
vis.tx.send(vis.arr.clone()).unwrap();
|
||||
}
|
||||
}
|
||||
fn complete(&mut self, rank: u8) {
|
||||
self.chart
|
||||
.set_label(&format!("{} - Complete - Rank #{}", self.name, rank));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +81,11 @@ fn main() {
|
|||
.map(|_| rand::rng().random_range(1.0..MAX_VALUE))
|
||||
.collect();
|
||||
|
||||
let sorts = [quick_sort, bubble_sort];
|
||||
let sorts: [(&str, Sorter); 3] = [
|
||||
("Quick Sort", quick::sort),
|
||||
("Bubble Sort", bubble::sort),
|
||||
("Merge Sort", merge::sort),
|
||||
];
|
||||
|
||||
let app = app::App::default().with_scheme(app::Scheme::Gtk);
|
||||
let theme = ColorTheme::new(&color_themes::fleet::DARK1);
|
||||
|
@ -127,7 +99,7 @@ fn main() {
|
|||
let mut visualizers = vec![];
|
||||
|
||||
for (i, sort) in sorts.into_iter().enumerate() {
|
||||
visualizers.push(SortVisualizer::new(i, arr.clone(), sort));
|
||||
visualizers.push(SortVisualizer::new(i, sort.0, arr.clone(), sort.1));
|
||||
}
|
||||
|
||||
thread::scope(|scope| {
|
||||
|
@ -141,11 +113,19 @@ fn main() {
|
|||
window.end();
|
||||
window.show();
|
||||
|
||||
let mut rank = 0;
|
||||
|
||||
app::add_idle3(move |_| {
|
||||
for sorter in &mut visualizers {
|
||||
let arr = sorter.rx.try_recv();
|
||||
if let Ok(arr) = arr {
|
||||
sorter.draw(arr);
|
||||
let data = sorter.rx.try_recv();
|
||||
if let Ok(data) = data {
|
||||
match data {
|
||||
SortMessage::Data(arr) => sorter.draw(arr),
|
||||
SortMessage::Done => {
|
||||
rank += 1;
|
||||
sorter.complete(rank);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
use std::sync::mpsc::Sender;
|
||||
|
||||
use crate::{SortMessage, SortVisualizer};
|
||||
|
||||
pub fn sort(vis: &mut SortVisualizer) {
|
||||
merge_sort(&vis.tx, &mut vis.arr.clone(), &vis.arr);
|
||||
|
||||
vis.tx.send(SortMessage::Done).unwrap();
|
||||
}
|
||||
|
||||
fn merge_sort(tx: &Sender<SortMessage>, og_arr: &mut [f64], arr: &[f64]) -> Vec<f64> {
|
||||
if arr.len() < 2 {
|
||||
arr.to_vec()
|
||||
}
|
||||
else {
|
||||
let n = arr.len() / 2;
|
||||
|
||||
let left = merge_sort(tx, og_arr, &arr[0..n]);
|
||||
let right = merge_sort(tx, og_arr, &arr[n..]);
|
||||
|
||||
merge(tx, og_arr, &left, &right)
|
||||
}
|
||||
}
|
||||
|
||||
fn merge(tx: &Sender<SortMessage>, og_arr: &mut [f64], left: &[f64], right: &[f64]) -> Vec<f64> {
|
||||
let mut i = 0;
|
||||
let mut j = 0;
|
||||
let mut merged: Vec<f64> = vec![];
|
||||
|
||||
while i < left.len() && j < right.len() {
|
||||
if left[i] < right[j] {
|
||||
merged.push(left[i]);
|
||||
i += 1;
|
||||
}
|
||||
else {
|
||||
merged.push(right[j]);
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if i < left.len() {
|
||||
while i < left.len() {
|
||||
merged.push(left[i]);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if j < right.len() {
|
||||
while j < right.len() {
|
||||
merged.push(right[j]);
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i, val) in merged.iter().enumerate() {
|
||||
og_arr[i] = *val;
|
||||
|
||||
tx.send(SortMessage::Data(og_arr.to_vec().clone())).unwrap();
|
||||
}
|
||||
|
||||
merged
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
use crate::{SortMessage, SortVisualizer};
|
||||
|
||||
pub fn sort(vis: &mut SortVisualizer) {
|
||||
let n = vis.arr.len();
|
||||
let low = 0;
|
||||
let high = n - 1;
|
||||
|
||||
quick_sort(vis, low, high);
|
||||
|
||||
vis.tx.send(SortMessage::Done).unwrap();
|
||||
}
|
||||
|
||||
fn quick_sort(vis: &mut SortVisualizer, low: usize, high: usize) {
|
||||
if low < high {
|
||||
let pivot = partition(vis, low, high);
|
||||
if pivot > 0 {
|
||||
quick_sort(vis, low, pivot - 1);
|
||||
}
|
||||
quick_sort(vis, pivot + 1, high);
|
||||
}
|
||||
}
|
||||
|
||||
fn partition(vis: &mut SortVisualizer, low: usize, high: usize) -> usize {
|
||||
let pivot = high;
|
||||
let mut i = low as isize - 1;
|
||||
|
||||
for j in low..high {
|
||||
if vis.arr[j] < vis.arr[pivot] {
|
||||
i += 1;
|
||||
vis.arr.swap(i as usize, j);
|
||||
vis.tx.send(SortMessage::Data(vis.arr.clone())).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
vis.arr.swap((i + 1) as usize, pivot);
|
||||
vis.tx.send(SortMessage::Data(vis.arr.clone())).unwrap();
|
||||
|
||||
(i + 1) as usize
|
||||
}
|
Loading…
Reference in New Issue