【図解】クイックソート:アルゴリズム【C言語】

本記事では、基本的なソートの一種である「クイックソート」のアルゴリズム解説・C言語による実装を確認していきます。

 

アルゴリズム解説では、図を用いた解説を行うため、イメージしやすい構成となっています

 

ソートは、アルゴリズムの中でも非常に基本的な分野なので、是非この機会にマスターしましょう。

 

 

 本記事でわかること

  • クイックソートの基本的な情報
  • アルゴリズムの流れ
  • C言語による実装方法

 

 

こちらの記事で、他のソートアルゴリズムをまとめています。

>>ソートアルゴリズム 計算量・特徴一覧

 

 

アルゴリズム入門書はこの一冊で十分!

 

 

 

クイックソートとは

クイックソートは、ソートアルゴリズムの一種であり、マージソートと同様、分割統治法を用いてソートを行うアルゴリズムです。

>>【図解】マージソート:アルゴリズム【C言語】

 

基本的な情報は以下になります。

 

最悪計算時間 \(O\) 安定性
\(O(n^2)\) 安定ではない

 

最悪計算時間は\(O(n^2)\)となっていますが、平均計算時間は\(O(nlog(n))\)であるため、クイックソートは比較的高速に動作します。

 

ちなみに、分割統治法とは、簡単に言うと、「大きな問題をそのまま解くのではなく、小さな問題に分割して、それぞれを解くことで、最終的に大きな問題を解く方法」のことを言います。

 

次の章で実例をお見せするので、今はピンと来なくても大丈夫です。

 

 

スポンサーリンク

 

クイックソートのアルゴリズム

まずは、軽く全体的な流れを確認し、その後、図を用いた説明へと移ります。

 

クイックソートのアルゴリズムは以下のようになります。

 

配列全体に対してquickSortを行う

 

quickSortでは以下の処理を行う

  1. 対象の配列をパーティションによって、左右2つの部分配列へと分割
  2. ①で分割した部分配列のうち、左側の配列に対してquickSortを行う
  3. ①で分割した部分配列のうち、右側の配列に対してquickSortを行う

 

quickSortの処理の中で、さらにquickSortを行うため、これは再帰的な処理になります。

 

文面だとよくわからないと思うので、さっそく実例を見ていきましょう。

 

 

では、サイズが8の配列で昇順ソートの具体例を見ていきます。

 

ここでは、配列の初期状態を次のようにします。

 

 

まずは、この配列全体を対象としてパーティションを適用し、並び替えを行います。

>>【図解】パーティション:アルゴリズム解説

 

一応、簡単にパーティションの概要を説明しておきます。

 

パーティションは、配列の中で基準値を1つ決め、その基準値を境にして、それよりも小さな値を基準値の左側へ、大きな値を右側へと移動するアルゴリズムです。

 

アルゴリズムの詳細気になる方は、上のリンクから飛んでみてください。

 

 

では、クイックソートに話を戻します。

 

最初の配列に対してパーティションを適用すると、このように並び替えることができます。

 

 

次に、基準値の左右にある部分配列に対して、再びパーティションを適用します。

 

 

左右それぞれの部分配列にパーティションを適用すると、以下のようになります。

 

 

図では2つの配列に分割していますが、実際は1つの配列内で並び替えているだけなので、実際の配列はこのようになっています。

 

 

では、先ほどと同様に、2つに分かれている部分配列に対して、さらにパーティションを適用していきます。

 

 

パーティション適用後は、このようになります。

 

 

これ以上は分割できないため、ここで処理は終了します。

 

再度確認しておくと、図ではいくつかの配列に分割しているように図示していますが、実際には、これらの処理は1つの配列内で行われます。

 

クイックソートでは、以下に示すように、1つの配列の中で並び替えを繰り返します

この点がマージソートと異なる点なので、注意してください。

 

 

ここまでがクイックソートアルゴリズムの動きとなります。

 

一度のパーティションで綺麗に二分割できた場合に、クイックソートの計算時間\(O(nlog(n))\)となり、高速に動作します。

 

逆に、パーティションで二分割した際に、左右のバランスが悪い場合は\(O(n^2)\)となり、そこまで高速ではなくなります。

 

 

1つ付け加えておくと、上で見てきた処理は、本来は再帰的な処理を行うので、上図とはパーテーションの順番が異なります。

気になる方は、コードから読み取ってください。

 

 

次の章では、これをC言語で実装していきます。

実際に自分の手で実装することで、より理解が深まるので、是非確認してみてください。

 

スポンサーリンク

 

クイックソートの実装【C言語】

さっそく、プログラム全体のコードを示します。

 

 

長々としていますが、クイックソート本体は、37~44行目の quickSort関数の中で実装しています。

 

見ていただけるとわかるように、 quickSort 関数内で、再び quickSort 関数を実行しているため、再帰的な処理を行っています。

 

正直、 quickSort 関数自体はそこまで難しくなく、どちらかというと partition 関数の方がわかりづらいと思います。

 

自分の手を動かして確認してみることで、理解が深まると思うので、納得いくまで色々いじってみてください。

 

では、今回はここまでとします。

お疲れさまでした。

 

別のソートを確認したい方は、ソートアルゴリズム 計算量・特徴一覧をご覧ください。