- 一、排序过程图示
- 二、算法详解
- 三、代码实现
-
- [3.1 整数和字符串型排序测试](#3.1 整数和字符串型排序测试)
- [3.2 自定义struct类型](#3.2 自定义struct类型)
- 四、代码性能测试
-
- [4.1 添加功能函数](#4.1 添加功能函数)
- [4.2 测试运行时间](#4.2 测试运行时间)
一、排序过程图示
二、算法详解
- 以
1, 9, 8, 13, 25, 0, 11
为例进行说明; - 假设第1个元素是最小值,从第二个数开始循环,找到更小的值(蓝色标注);
- 第一轮比较结束后,将假设最小值和实际最小值互相调换,则红色的部分为排序好的数序;
- 第二轮比较找到的实际最小值为倒数第二个数,因此与假设的最小值9相调换;
- 第三轮假设的最小值就是实际的最小值,因此维持原样;
- 以此类推完成最终的排序;
三、代码实现
3.1 整数和字符串型排序测试
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]);
}
}
运行结果
- 由下面的运行结果可以看到,
string
和int
类型的测试用例都过了;
3.2 自定义struct类型
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);
}
- 使用的测试序列长度十倍十倍的增加;
- 最后的结果如下 (恐怖的耗时增长)