アルゴリズムと データ構造 第8回 ソート・その2 単純挿入ソート 単純挿入ソートとは 順に要素に着目し、それを適当な位置に挿入 別名:シャトルソート 6 1 4 3 4 1 7 3 9 8 8 単純挿入ソート 目的列と原列 目的列:ソート済みの部分 原列:これからソートする部分 単純挿入ソートのアルゴリズム 原列の先頭要素を目的列の適当な位置に挿入 1 4 6 目的列 7 3 9 原列 8 単純挿入ソート 「適当な位置に挿入」の実現 左隣の要素と比較し、挿入すべき値より大きけれ ば左隣の値を代入 挿入する値以下の要素に出会ったところに挿入 1 4 6 4 7 6 3 7 9 8 単純挿入ソート 「適当な位置に挿入」のアルゴリズム 原列左端の値を保存 目的列の右端から、保存した値と比較 目的列左端に達するか、保存した値と等しいか 小さいキーを持った値を持つ項目が見つかったら その位置に保存していた値を挿入 安定性 飛び越えた要素の交換が行われないので安定 単純挿入ソート 単純挿入ソートのプログラム for (i = 1; i < n; i++) { int tmp = a[i]; for (j = i; j > 0 && a[j - 1] > tmp; j--) a[j] = a[j - 1]; a[j] = tmp; } シェルソート 単純挿入ソートの特徴 ソート済みに近い場合は高速 挿入先が遠く離れていると移動回数が増大 1 0 2 1 3 2 4 3 5 4 0 5 6 シェルソート シェルソートの考え方 単純挿入ソートの長所を生かしつつ、回数の多 い移動を避ける 最初にまずグループ化を行い、グループ内で大 まかにソート(地ならし) グループを次第に小さくしていき、最終的に単純 挿入ソートを行ってソート完了 前処理を含めても、移動回数が少なくてすみ、全 体として高速化 シェルソート シェルソートの実例 4-ソート 8 7 1 4 3 2 7 8 6 3 4 5 シェルソート シェルソートの実例 2-ソート 3 7 1 4 3 2 7 8 6 5 8 4 5 6 シェルソート シェルソートの実例 1-ソート 1 3 1 3 2 3 4 2 4 5 7 7 6 5 7 8 8 6 シェルソート シェルソートのプログラム for (h = n / 2; h > 0; h / 2) for (i = h; i < n; i++) { int tmp = a[i]; for (j = i - h; j >= 0 && a[j] > tmp; j -= h) a[j + h] = a[j]; a[j + h] = tmp; } シェルソート 増分の選択 ある値から減少して1になればよい 増分のとり方によっては、同じグループ内でのみ ソートして、グループ分けが十分に機能しなくなる 増分が互いに倍数にならないようにする h = ・・・、121、40、13、4、1 1から始め、3倍して1を足していく 最初が大きすぎても効果なし:n / 9を超えない値 シェルソート 適切増分シェルソートのプログラム for (h = 1; h < n / 9; h = h * 3 + 1) ; for ( ; h > 0; h /= 3) for (i = h; i < n; i++) { int tmp = a[i]; for (j = i - h; j >= 0 && a[j] > tmp; j -= h) a[j + h] = a[j]; a[j + h] = tmp; }
© Copyright 2024 ExpyDoc