だめだったか。おれには関係ないやとマイペースな柴犬です。
sort 部分の見直し
次のようにソート部分を見直しましたが、残念ながら効果は感じられませんでした。
クイックソートから外れますが、構造体を要素にしたベクトルを作ってみて、O’reilly プログラミングRust第2版にある16.2.8 ソートと検索にある次のコードを使ってどのくらいでできるのか確かめたいと思います。
students.sort_by(|a, b| {
let a_key = (&a.last_name, &a.first_name);
let b_key = (&b.last_name, &b.first_name);
a_key.cmp(&b_key)
});
引き続き考えてみます。
fn partition<T: PartialOrd + Clone>( elements: &mut Vec<Vec<T>>, left: usize, right: usize, ) -> usize { let pivot1 = elements[left][0].clone(); let pivot2 = elements[left][1].clone(); let mut i = left + 1; let mut j = right; loop { // i, j の取り得る範囲は left + 1 <= i, j <= right // 条件を満たす限り i を進めます。 while i <= right && (elements[i][0].clone() < pivot1 || (elements[i][0].clone() == pivot1 && elements[i][1].clone() < pivot2)) { i += 1; } // 条件を満たす限り j を進めます。 // 同値に対応するため .clone() > pivot2 を .clone() >= pivot2 としました。 while j >= left + 1 && (elements[j][0].clone() > pivot1 || (elements[j][0].clone() == pivot1 && elements[j][1].clone() >= pivot2)) { j -= 1; } // 交差になれば入れ替えます。 if i >= j { break; } swap(elements, i, j); } // ピボットを正しい位置にセットします。 swap(elements, left, j); return j as usize; } fn swap<T: PartialOrd + Clone>(elements: &mut Vec<Vec<T>>, i1: usize, i2: usize) { if i1 < i2 { let mut temp = elements[i2][0].clone(); elements[i2][0] = elements[i1][0].clone(); elements[i1][0] = temp; temp = elements[i2][1].clone(); elements[i2][1] = elements[i1][1].clone(); elements[i1][1] = temp; } } fn quicksort<T: PartialOrd + Clone>(elements: &mut Vec<Vec<T>>, left: usize, right: usize) { if left < right { let pivot = partition(elements, left, right); // オーバーフローのエラーがでるが // 実際は pivot == 0 になると underflow エラー if pivot < 1 { quicksort(elements, left, left); } else { quicksort(elements, left, pivot - 1); } quicksort(elements, pivot + 1, right); } }
今回の QuickSort
ここで、P、A、B が同値で、P がピボットである下の図の場合を考えてみます。
P をピボットの位置とします。i は条件を満たすか否かを判定しながら右へ進みます。そして条件を満たさない A の位置で止まります。
次に j を考えます。
不等号 > の場合
j は条件を満たすか否かを判定しながら左へ進みます。そして条件を満たさない B の位置で止まります。
この場合、交差は起こらないので A と B の交換が行われます。
しかし、次のループでも i と j は条件を満たさないので進めません。
したがって、無限ループが発生します。
不等号 >= の場合
j は条件を満たすか否かを判定しながら左へ進みます。そして条件を満たさない C の位置で止まります。
この場合、i > j となり交差が発生します。
そして、P と C を交換します。図で分かるとおり C の位置がソートしたときの P の位置です。この位置は今後変わりません。
また、C の位置がピボットより小さい領域、大きい領域を分ける分水嶺となります。