2011 年度「計算数学」 2012-01-06

§43 ソートの安定性

(43.1) この節は、課題が早く終わって時間が余った人のためのものである。 前に (25.4) で述べた、 ソート前のデータに同じ値のものがあった場合の問題を考えよう。

(43.2) あるソートのアルゴリズムが「安定 (stable)」であるとは、 同じ値のものが、ソート後も元の順序を保っていることをいう。 あるソートアルゴリズムが安定であることをいうには、 数学の定理と同様に証明が必要であり、 不安定(あるいは非安定)であることをいうには反例をもって示すべきであるが、 実験で試し、その結果を参考にすることができる。

(43.3) この授業で書いているプログラムを少し改変することで、 その実験が行なえる。以下では、そのやり方の一つを説明する。 プログラムのコピーを、次のように改変する。

(43.4) 以上のように改変してから実行する。 ソート後、a[i] の値が同じものが並んだら、 それらの中で b[i] の値が小さい順かどうかを調べる。

(43.5) 配列の大きさ N を画面の一行に収まるぐらいとし、 途中の過程をすべて出力させて実験すれば、 どの過程で安定性が崩れるのかをも見ることができる。

(43.6) 配列の大きさを大きくして試したい場合、 安定かどうかを目で見て判定するのは大変であろう。 print() は呼ばないようにし、 main() の最後に安定かどうかをチェックする部分をつけるとよい。

(43.7) この授業の課題では、 同じ値をもつものはないと考えてプログラムを書いてきた。 そのため、 comp(i, i+1) > 0 のように、 関数 comp() の次には等号なしの不等号がきているであろう。 そこを、 等号つきの不等号で置き換えても正しいプログラムであるかどうか確認せよ。 正しいならば、そのプログラムでも実験を行ない、 等号なしの場合と比べて、比較・交換回数がどう変わるか調べてみよ。 その際には、同じ値をもつものが多くあるほうが違いがわかりやすいので、 N の値を大きくし、かつ、 初期化は a[i] = rand() % 99 + 1; などとするのもよい。


岩瀬順一