赞
踩
开始:从数组的第一个元素开始,假设最小(或最大)元素就是第一个元素。
比较:遍历未排序的部分,找到实际的最小(或最大)元素。
交换:将找到的最小(或最大)元素与未排序部分的第一个元素交换位置。
重复:移动到下一个元素,重复步骤2和3,直到数组完全排序。
在Rust中,我们可以通过以下步骤实现选择排序的可视化:
定义状态:首先,定义一个枚举SortState来表示排序的不同状态,如Idle、Sorting、Paused等。
实现选择排序步骤:创建一个函数selection_sort_step,该函数每次调用时执行一步选择排序。该函数需要记录当前的索引位置,并在每次调用时更新。
可视化设置:在主函数中,设置Piston窗口库创建可视化窗口,并初始化一组乱序数组。
事件循环:在Piston的事件循环中,根据当前的排序状态和用户输入(如开始、暂停、单步执行等),调用selection_sort_step函数执行排序步骤,并更新窗口以显示当前数组的状态。
绘制数组:每次循环时,根据数组中每个元素的值绘制对应的矩形条,以可视化地表示数组的当前状态。
extern crate piston_window; use piston_window::*; use std::time::{Duration, Instant}; #[derive(PartialEq)] enum SortState { Idle, Sorting, Paused, Step, } fn selection_sort_step(numbers: &mut Vec<i32>, current_index: &mut usize) -> bool { if *current_index < numbers.len() - 1 { let mut min_index = *current_index; for i in (*current_index + 1)..numbers.len() { if numbers[i] < numbers[min_index] { min_index = i; } } numbers.swap(*current_index, min_index); *current_index += 1; true } else { false // 排序完成 } } fn draw_numbers(window: &mut PistonWindow, e: &Event, numbers: &[i32], current_index: usize) { window.draw_2d(e, |c, g, _| { clear([1.0; 4], g); // 用白色清空背景 let size = numbers.len(); let window_size = c.get_view_size(); let bar_width = window_size[0] / size as f64; for (i, &number) in numbers.iter().enumerate() { let x = i as f64 * bar_width; let y = window_size[1] - window_size[1] * (number as f64 / size as f64); rectangle( if i == current_index { [1.0, 0.0, 0.0, 1.0] } else { [0.0, 0.0, 1.0, 1.0] }, // 当前索引红色,其余蓝色 [x, y, bar_width, window_size[1] - y], c.transform, g, ); } }); } fn main() { let mut window: PistonWindow = WindowSettings::new("Selection Sort Visualization", [800, 600]) .exit_on_esc(true) .build() .unwrap(); let mut numbers = vec![10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; let mut current_index = 0usize; let mut sort_state = SortState::Idle; let mut last_update_time = Instant::now(); let update_delay = Duration::from_millis(500); while let Some(e) = window.next() { if let Some(Button::Keyboard(key)) = e.press_args() { match key { Key::S => sort_state = SortState::Sorting, Key::P => sort_state = SortState::Paused, Key::N => { if sort_state == SortState::Paused || sort_state == SortState::Idle { sort_state = SortState::Step; } }, Key::R => { numbers = vec![10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; current_index = 0; sort_state = SortState::Idle; }, _ => {} } } if sort_state == SortState::Sorting || sort_state == SortState::Step { if last_update_time.elapsed() >= update_delay { if !selection_sort_step(&mut numbers, &mut current_index) && sort_state == SortState::Sorting { sort_state = SortState::Paused; // 排序完成自动暂停 } last_update_time = Instant::now(); if sort_state == SortState::Step { sort_state = SortState::Paused; // 单步执行后暂停 } } } draw_numbers(&mut window, &e, &numbers, current_index); } }
extern crate piston_window; use piston_window::*; use std::time::{Duration, Instant}; #[derive(PartialEq)] enum SortState { Idle, Sorting, Paused, Step, } fn selection_sort_step(numbers: &mut Vec<i32>, current_index: &mut usize) -> bool { if *current_index < numbers.len() - 1 { let mut min_index = *current_index; for i in (*current_index + 1)..numbers.len() { if numbers[i] < numbers[min_index] { min_index = i; } } numbers.swap(*current_index, min_index); *current_index += 1; true } else { false // 排序完成 } } fn draw_numbers(window: &mut PistonWindow, e: &Event, numbers: &[i32], current_index: usize) { window.draw_2d(e, |c, g, _| { clear([1.0; 4], g); // 用白色清空背景 let size = numbers.len(); let window_size = c.get_view_size(); let bar_width = window_size[0] / size as f64; for (i, &number) in numbers.iter().enumerate() { let x = i as f64 * bar_width; let y = window_size[1] - window_size[1] * (number as f64 / size as f64); rectangle( if i == current_index { [1.0, 0.0, 0.0, 1.0] } else { [0.0, 0.0, 1.0, 1.0] }, // 当前索引红色,其余蓝色 [x, y, bar_width, window_size[1] - y], c.transform, g, ); } }); } fn main() { let mut window: PistonWindow = WindowSettings::new("Selection Sort Visualization", [800, 600]) .exit_on_esc(true) .build() .unwrap(); let mut numbers = vec![10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; let mut current_index = 0usize; let mut sort_state = SortState::Idle; let mut last_update_time = Instant::now(); let update_delay = Duration::from_millis(500); while let Some(e) = window.next() { if let Some(Button::Keyboard(key)) = e.press_args() { match key { Key::S => sort_state = SortState::Sorting, Key::P => sort_state = SortState::Paused, Key::N => { if sort_state == SortState::Paused || sort_state == SortState::Idle { sort_state = SortState::Step; } }, Key::R => { numbers = vec![10, 5, 3, 8, 2, 6, 4, 7, 9, 1]; // 可以考虑添加一个函数来生成随机或特定的数字序列 current_index = 0; sort_state = SortState::Idle; }, _ => {} } } if sort_state == SortState::Sorting || sort_state == SortState::Step { if last_update_time.elapsed() >= update_delay { if !selection_sort_step(&mut numbers, &mut current_index) && sort_state == SortState::Sorting { sort_state = SortState::Paused; // 排序完成自动暂停 } last_update_time = Instant::now(); if sort_state == SortState::Step { sort_state = SortState::Paused; // 单步执行后暂停 } } } draw_numbers(&mut window, &e, &numbers, current_index); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。