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 fltk_theme::{color_themes, ColorTheme};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
const SIZE: u32 = 50;
|
mod bubble;
|
||||||
|
mod merge;
|
||||||
|
mod quick;
|
||||||
|
|
||||||
|
const SIZE: u32 = 100;
|
||||||
const MAX_VALUE: f64 = 100.0;
|
const MAX_VALUE: f64 = 100.0;
|
||||||
|
|
||||||
type Sorter = fn(&mut SortVisualizer);
|
type Sorter = fn(&mut SortVisualizer);
|
||||||
|
|
||||||
#[derive(Debug)]
|
enum SortMessage {
|
||||||
struct SortVisualizer {
|
Data(Vec<f64>),
|
||||||
arr: Vec<f64>,
|
Done,
|
||||||
chart: Chart,
|
|
||||||
sorter: Sorter,
|
|
||||||
tx: Sender<Vec<f64>>,
|
|
||||||
rx: Receiver<Vec<f64>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SortVisualizer {
|
#[derive(Debug)]
|
||||||
fn new(id: usize, arr: Vec<f64>, sorter: Sorter) -> Self {
|
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 (tx, rx) = mpsc::channel();
|
||||||
let y = 300 * (id) as i32;
|
let y = 300 * (id) as i32;
|
||||||
|
|
||||||
|
@ -37,9 +47,11 @@ impl SortVisualizer {
|
||||||
chart.set_size(500, 250);
|
chart.set_size(500, 250);
|
||||||
chart.set_frame(FrameType::FlatBox);
|
chart.set_frame(FrameType::FlatBox);
|
||||||
chart.set_bounds(0.0, MAX_VALUE);
|
chart.set_bounds(0.0, MAX_VALUE);
|
||||||
|
chart.set_label(name);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
arr,
|
arr,
|
||||||
|
name,
|
||||||
chart,
|
chart,
|
||||||
sorter,
|
sorter,
|
||||||
tx,
|
tx,
|
||||||
|
@ -57,54 +69,10 @@ impl SortVisualizer {
|
||||||
self.chart.add(*i, "", Color::Cyan);
|
self.chart.add(*i, "", Color::Cyan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn quick_sort(vis: &mut SortVisualizer) {
|
fn complete(&mut self, rank: u8) {
|
||||||
let n = vis.arr.len();
|
self.chart
|
||||||
let low = 0;
|
.set_label(&format!("{} - Complete - Rank #{}", self.name, rank));
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +81,11 @@ fn main() {
|
||||||
.map(|_| rand::rng().random_range(1.0..MAX_VALUE))
|
.map(|_| rand::rng().random_range(1.0..MAX_VALUE))
|
||||||
.collect();
|
.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 app = app::App::default().with_scheme(app::Scheme::Gtk);
|
||||||
let theme = ColorTheme::new(&color_themes::fleet::DARK1);
|
let theme = ColorTheme::new(&color_themes::fleet::DARK1);
|
||||||
|
@ -127,7 +99,7 @@ fn main() {
|
||||||
let mut visualizers = vec![];
|
let mut visualizers = vec![];
|
||||||
|
|
||||||
for (i, sort) in sorts.into_iter().enumerate() {
|
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| {
|
thread::scope(|scope| {
|
||||||
|
@ -141,11 +113,19 @@ fn main() {
|
||||||
window.end();
|
window.end();
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
|
let mut rank = 0;
|
||||||
|
|
||||||
app::add_idle3(move |_| {
|
app::add_idle3(move |_| {
|
||||||
for sorter in &mut visualizers {
|
for sorter in &mut visualizers {
|
||||||
let arr = sorter.rx.try_recv();
|
let data = sorter.rx.try_recv();
|
||||||
if let Ok(arr) = arr {
|
if let Ok(data) = data {
|
||||||
sorter.draw(arr);
|
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