キャリテク!マガジン
- TOP
- キャリテク!マガジン
- 整列アルゴリズム(2)
整列アルゴリズム(2)
こんにちは。小澤です。
前回は、基本情報技術者試験における整列アルゴリズムの一部、バブルソート、選択ソート、挿入ソート、シェルソートについて解説しました。
今回は、クイックソート、ヒープソート、マージソートを取り上げ、これらのアルゴリズムについて理解を深めていきましょう。
これらのアルゴリズムについては、『徹底攻略 基本情報技術者試験教科書 令和5年度』の「2−10 整列アルゴリズム(124ページから125ページ)」で解説がなされています。
クイックソート
クイックソートは、分割統治法の考え方を利用した代表的なソートアルゴリズムの一つです。
分割統治法というのは、大きな問題を小さな部分問題に分割し、それぞれの部分問題を解決することで全体の問題を解決しようとするアルゴリズムデザインの手法です。
与えられた問題を2つかそれ以上に分割(分解)し、部分問題を再帰的に解いていき、その結果を統合(合成)して元の問題の解を得る手法です。
このメリットは、複雑な問題をより単純な形に分割できることです。
また、並列処理が可能であるため、計算量や処理時間を大幅に改善できます。
また、再帰的というのは、ある関数や手続きが自分自身を呼び出すことを意味します。
再帰的なアプローチは、分割統治法の一部としてよく利用されます。
クイックソートの基本的な手順は以下の通りです。
- ソート対象の配列から1つの要素を選び、これを基準値(ピボット)とする。
- 配列を2つに分割する。基準値より小さい値は左側、大きい値は右側に配置する。これを分割(パーティション)する。
- 左右それぞれの部分配列に対して、再帰的に処理を繰り返す。
クイックソートのメリットとしては、以下のようなものがあげられます。
- 平均的には他のソートに比べて高速(選んだ基準値に左右される)
- アルゴリズムが単純
- 追加メモリを必要とせず入力配列上の要素の入れ替えのみでソートを実行できる(この処理をinplaceなアルゴリズムという)
疑似言語による実装については、過去の問題を参照してください。
ヒープソート
ヒープソートも分割統治法に基づくアルゴリズムで、ヒープ構造を作りながらデータをソートする特徴的な手法を用います。
ヒープとは、ヒープ順序特性を持つ完全二分木(または近似的に完全な二分木)のことをいいます。
各ノードのキーの値は、その子ノードのキーの値よりも大きい(最大ヒープ)あるいは、小さい(最小ヒープ)という特性を持ちます。
ヒープソートでは、このヒープの特性を利用して、最大値(または最小値)を効率的に取り出すことでソートを行います。
要素の追加や削除によってヒープの順序性が損なわれないようにするため、木の再構築が必要になります。
ヒープソートの概要は以下です。
- ソート対象の配列を最大ヒープに構築する
・末尾要素の親ノードから順にシフトダウンさせる(要素を下の階層へ移動させる) - ルートノード(最大値)を取り出して配列の最後に移動
- 取り出された部分に新しい要素を入れる
・子ノードとの大小関係を満たすようにシフトダウン - 配列のサイズを1つ減らす
- 2〜4のステップを繰り返す
・順に最大値が選ばれていき、昇順になる
つまり、構築したヒープから最大値を取り出していき、残った部分を再構築する、というアプローチです。
ヒープソートのメリットとしては以下があげられます。
- アルゴリズムが比較的単純
- 最悪のケースでも計算量はO(nlogn)が保証される(クイックソートの最悪のケースは避けられる)
一方で、入れ替え回数が多く、実装が複雑というデメリットがあります。
マージソート
マージソートはマージ(統合)と呼ばれる操作を使用してソートを行う方法です。再帰的にデータを分割し、それをマージしてソートします。
マージソートは以下のステップで構成されます。
- ソート対象の配列を再帰的に2つに分割する
・配列が1要素になったら分割を止める - 分割された2つの小さな配列をそれぞれマージソートする
・1要素の配列はすでにソート済みとみなす - 上記でソート済みになった2つの配列を、正しい順番にマージする
・左右の配列の先頭要素を比較し、小さい方を結果配列にコピー
・コピーした方の配列のインデックスをインクリメント
・上記をループで繰り返す - すべての小配列がマージされるまで1〜3を繰り返す
つまり、「分割」→「再帰的なソート」→「マージ」を繰り返していくイメージです。各ステップで分割とマージを繰り返すため、安定してO(n log n)の実行時間がかかります。ただし、追加のメモリ(バッファ)が必要であることがデメリットです。
まとめ
今回は、整列アルゴリズムのうち、クイックソート、ヒープソート、マージソートについて説明しました。
クイックソートは一般的に高速で実装が簡単ですが、最悪の場合には性能が低下する可能性があります。ランダムなデータに対しては効果的です。
ヒープソートは安定して高速なアルゴリズムであり、外部のデータへのアクセスが少ないため、大規模なデータセットに適しています。
マージソートは安定しており、データセットのサイズが大きい場合でも一貫して高いパフォーマンスを発揮しますが、追加のメモリが必要です。 選択するアルゴリズムは、使用状況や特定の制約によって異なります。ソートされるデータの性質やデータセットのサイズ、そしてメモリの利用や実装の複雑さなどを総合的に判断して、最適なアルゴリズムを選択することが重要です。