【算法】选择排序

一、排序过程图示

二、算法详解

  1. 1, 9, 8, 13, 25, 0, 11为例进行说明;
  2. 假设第1个元素是最小值,从第二个数开始循环,找到更小的值(蓝色标注);
  3. 第一轮比较结束后,将假设最小值和实际最小值互相调换,则红色的部分为排序好的数序;
  4. 第二轮比较找到的实际最小值为倒数第二个数,因此与假设的最小值9相调换;
  5. 第三轮假设的最小值就是实际的最小值,因此维持原样;
  6. 以此类推完成最终的排序;

三、代码实现

3.1 整数和字符串型排序测试

lib.rs

rust 复制代码
pub fn select_sort<T: PartialOrd>(src: &mut Vec<T>){
    let length = src.len();

    for i in 0..length{ //从元素的起始开始循环

        let mut min_index  = i; //当前设为最小值

        for j in i+1..length{  //从下一数开始比较
            if &src[j] < &src[min_index]{  //满足条件时保存下标
                min_index = j;
            }
        }

        if min_index != i {
            src.swap(min_index, i); //当假设的最小值与实际的最小值下标不相同时,完成交换
        }
    }
}

#[cfg(test)]
mod tests{
    use super::*;

    #[test]
    fn select_sort_string_test(){
        let mut num = vec!["String", "China"];
        select_sort(&mut num);
        assert_eq!(num, ["China", "String"]);
    }

    #[test]
    fn select_sort_i32_test(){
        let mut num = vec![ 1, 9, 8, 13, 25, 0, 11];
        select_sort(&mut num);
        assert_eq!(num, [0, 1, 8, 9, 11, 13, 25]);
    }
}

运行结果

  • 由下面的运行结果可以看到,stringint类型的测试用例都过了;

3.2 自定义struct类型

main.rs

rust 复制代码
use testrust::*;

#[derive(Debug)]
#[derive(PartialEq)]
struct Student{
    score: f64,
    name: String,
}

impl Student {
    fn new(score: f64, name: String) -> Student{
        Student{
            score,
            name,
        }
    }
}

impl PartialOrd for Student{
    fn ge(&self, other: &Self) -> bool {
        self.score >= other.score
    }

    fn gt(&self, other: &Self) -> bool {
        self.score > other.score
    }

    fn le(&self, other: &Self) -> bool {
        self.score <= other.score
    }

    fn lt(&self, other: &Self) -> bool {
        self.score < other.score
    }

    //不知道如何用,先返回None
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        None
    }
}

fn main() {
    let mut stus= [Student::new(98.5, String::from("李阳")),
                                   Student::new(85.3, String::from("王小伍")),
                                   Student::new(60.5, String::from("陈龙")),
                                   Student::new(85.3, String::from("陈小川"))];
    
    select_sort(&mut stus);
    println!("{:#?}", stus);
}
  • 为自定义结构体类型添加排序功能;
  • 以学生的分数作为排序准则;
  • 结果如下;

四、代码性能测试

4.1 添加功能函数

  • 自动生成数组
rust 复制代码
use rand::Rng;
pub fn get_range_list(total: u32, begin: u32, end: u32) -> Vec<u32>{
    let mut ret = Vec::new();
    let mut rng = rand::thread_rng();
    assert!(begin <= end);

    for _i in 0..total{
        ret.push(rng.gen_range(begin..=end));
    }

    ret
}

函数以生成总个数、开始生成数以及结束生成数三个参数形成一个总数为total的[begin, end]的列表;

  • 算法运行时间测试;
rust 复制代码
use std::time::Instant;
pub fn test_sort_running_time<T>(func: fn(src: &mut Vec<T>), src: &mut Vec<T>){
    let start_time = Instant::now();
    func(src);
    let during_time = start_time.elapsed();

    println!("函数运行时间: {:?}", during_time)
}
  • 先引入Instant
  • test_sort_running_time函数传入一个函数指针以及传递给该函数的参数的参数;
  • 最后计算运行时间;

4.2 测试运行时间

rust 复制代码
fn main() {
    
    let mut lists = get_range_list(100, 0, 100);
    test_sort_running_time(select_sort, &mut lists);

    lists = get_range_list(1000, 0, 1000);
    test_sort_running_time(select_sort, &mut lists);

    lists = get_range_list(10_000, 0, 10_000);
    test_sort_running_time(select_sort, &mut lists);

    lists = get_range_list(100_000, 0, 100_000);
    test_sort_running_time(select_sort, &mut lists);
}
  • 使用的测试序列长度十倍十倍的增加;
  • 最后的结果如下 (恐怖的耗时增长)
相关推荐
深圳市快瞳科技有限公司1 小时前
个体识别、行为解读、健康管理:多模态宠物AI大模型的场景化落地
人工智能·算法·计算机视觉·大模型·多模态·宠物·宠物ai识别
liulilittle1 小时前
归一化:激活函数
人工智能·算法·机器学习·llm
Mem0rin3 小时前
前缀和:一维与二维
数据结构·算法
小趴蔡ha3 小时前
12 K-Means 聚类入门:没有标签如何发现数据分组
算法·kmeans·聚类
-dzk-3 小时前
【二叉树】LC 101.对称二叉树
算法·二叉树
白狐_7983 小时前
408数据结构第6章:图——核心考点、算法对比与AOE网真题
数据结构·算法
变量未定义~3 小时前
DFS之剪枝与优化-小猫爬山、 数独、 木棒
算法
Navigator_Z4 小时前
LeetCode //C - 1187. Make Array Strictly Increasing
c语言·算法·leetcode
龍德明宇4 小时前
如何理解大语言模型的负主体性-龍德明宇
人工智能·算法·大语言模型llm·负主体性·ai存在论
白狐_7985 小时前
408数据结构第6章:迪杰斯特拉(Dijkstra)算法——真题精讲
数据结构·算法