当前位置:   article > 正文

学习选择排序的可视化实现(一)

学习选择排序的可视化实现(一)

学习选择排序的可视化实现(一)

选择排序的基本思路

开始:从数组的第一个元素开始,假设最小(或最大)元素就是第一个元素。
比较:遍历未排序的部分,找到实际的最小(或最大)元素。
交换:将找到的最小(或最大)元素与未排序部分的第一个元素交换位置。
重复:移动到下一个元素,重复步骤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);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97

优化版本:

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);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/533274
推荐阅读
相关标签
  

闽ICP备14008679号