Rust で乱数や構造体の配列を使ってバブルソートを行う

株式会社プライムストラクチャーのエンジニアのSayaです。

今回は Rust で配列になった構造体のバブルソート行うことで、構造体の作成、構造体の配列化、乱数の生成、配列の入れ替えを実装しようと思います。

バブルソートとは

ソートアルゴリズムの1つで、隣り合う値の大小を比較しながら整理します。
他のソートアルゴリズムに比べて実装が容易なのが特徴です。

検証環境

この検証は以下の環境で行いました。

macOS Mojave 10.14.6
Docker Engine 19.03.1
Docker Compose 1.24.1
rustc 1.36.0

乱数の作成

乱数は以下のように生成できます。
cargo.tomlファイルに以下のパッケージを追加し、実行時にインストールされるようにします。
https://crates.io/crates/rand

<Cargo.toml>
[dependencies]
rand = "0.7"
rand::thread_rng();で乱数を初期化する必要があります。
main.rs
use rand::Rng;
let mut rng = rand::thread_rng();
let r = rng.gen_range(最小値, 最大値);

構造体の宣言

構造体は以下のように宣言できます。

struct User {
    name: String,
    age: i32,
}

struct 構造体名 {
  プロパティ名: 型
}

構造体配列の宣言

構造体配列は以下のように宣言できます。

let mut users: Vec<User> = Vec::with_capacity(num);

let 変数名 : Vec<構造体名> = Vec::with_capacity(配列の個数);

配列内の入れ替え

配列内の入れ替えは以下のように行います。

配列.swap(入れ替えるindex番号A、入れ替えるindex番号B)

https://doc.rust-lang.org/std/vec/struct.Vec.html?search=#method.swap

バブルソートを実装する

これらの乱数と構造体を使ってバブルソートを実装します。
以下のような Rust ファイルを作成します。

<main.rs>
use rand::Rng;

// 年齢と名前を持った構造体
struct User {
    name: String,
    age: i32,
}

fn main() {
    // ユーザ一覧作成
    let num = 20;
    let mut rng = rand::thread_rng();
    let mut users: Vec<User> = Vec::with_capacity(num);
    for i in 0..num {
        users.push(
            User {
                name: i.to_string(),
                age: rng.gen_range(0, 120)
            }
        );
    }

    // バブルソート
    let size = users.len() - 1;
    for i in 0..size {
        for j in 0..(size - i) {
            if users[j].age > users[j + 1].age {
                users.swap(j, j + 1)
            }
        }
    }

    // 表示
    for user in &users {
        println!("No.{}: age {}", user.name, user.age);
    }
}

実行する

作成した Rust ファイルを実行します。

$ cargo run

すると以下のようにバブルソートが始まります。

まとめ

今回は Rust で配列になった構造体のバブルソート行うことで、構造体の作成、構造体の配列化、乱数の生成、配列の入れ替えを実装していきました。

Rust は他の言語に比べてかっちりとした型宣言を行う必要があります。
そのためビルド時のエラーに注意が必要です。

参考文献

構造体