ソートについて


Home
●ソート関数が無いのは不便ですね
VBAプログラムの中で数件、十数件程度のデータを並べ替えたいというのは
よくあることだと思いますが、そんな時みなさんはどうされていますか。

ネットの掲示板の回答でよくあるのは、
シートを利用してエクセルの並べ替え機能を使えというものです。
ところがこのシートを使った並べ替え、便利なようでなかなか面倒です。
また、シートやブックの番号(Book2とかSheet3などの連番)が無意味に増えてゆく
のが私個人的にはあまり好きではありません。

もっと簡単に配列のソートが出来ても良さそうなものなのに、ExcelVBAにはその関数が
備わっていないのです。実に残念です。

そこで無いものは作ればよい、ということでソート関数を自分で作って利用している方も
多いのではないかと思います。ソートのように色々な場面で利用できる関数は汎用的なものを
ひとつ作っておけば済みますので。
(でも実はこの汎用的に作っておくというのが案外大変なのですが。^^;)

●一長一短のアルゴリズム
ところでソートと一口に言っても色々なアルゴリズムがあり、それぞれ一長一短があります。
詳しい解説などはネットで検索すれば山ほど出てきますのでそちらにゆだねるとして、
少ない私の知識で知っている範囲の一部を紹介すると次のような感じです。
バブルソートアルゴリズムが単純、コードは短くて済む、少量のデータ向け
挿入ソートほとんど並べ替え出来ている場合は超高速、逆順&多量データだと使い物にならぬほど低速
シェルソート速いがアルゴリズムが結構複雑
クイックソート超高速だがデータの並び方によっては激遅になる場合がある
コムソートバブルソートの改良版で、どんなデータに対してもかなり速い方

●お気に入りのアルゴリズムはコムソート
私個人的に一番気に入っているのはコムソートです。
アルゴリズムが比較的単純
クイックソートほどは速くないものの、かなり速い部類に入る
クイックソートなどのようにデータの並び方によって激遅になるということがない
という点が気に入っており、掲示板の回答でも度々推奨しています。

私の「エクセルVBA小技集」にもいくつかのソートプログラムを載せていますが、
それぞれ一応作ってみたので載せてみたというレベルの作りでしかありません。

コムソートと安定化コムソートは一応ある程度実用に耐える作りにはしてありますが
やはりこれだけでオールマイティーに使えるソート関数というわけには行きません。

●「アドインの素」のソート関数はいかがですか
今現在のお気に入りはコムソートですが、実はコムソートの存在を知る前に
色々なアルゴリズムの勉強をして、クイックソートを基本にした
実用的なソート関数を作っていました。
そしてそれを、「アドインの素」というソフトに組み入れて公開しています。

(アドインの素はシェアウェアですが、ソート関数はフリーソフトです。
 ソート関数は試用期間終了後も継続して使用可能です。)

どんな場合でも使えて高速なアルゴリズムというのはあり得ませんので、
同ソフトはクイックソートのアルゴリズムを中心に独自な工夫を加えて、またデータの内容によって
処理を分けたりというようなことをして、「実用的」な処理を実現しています。

処理速度は私が実験した限りでは概ね、
クイックソート>「アドインの素」のソート関数>コムソート>安定化コムソート>....>バブルソート
の順でした。

(「アドインの素」のソート関数中でクイックソートを使っているのにクイックソートより遅いというのは、
その中では実用的に使えるようにするために前処理後処理などが付加されているためです。
そのため、純粋なアルゴリズムそのままで作ったテスト用のクイックソートより遅いということです。

つまり、より高速処理を追及するなら対象データに即した形で余計な処理を付加しないようにして
プログラム中に組み込んでしまうことが一番だということです。当たり前ですが。^^;)

●何を使うかはcase by case
私の作ったソートプログラムについてまとめてみました。
ソート種別長所短所備考適用範囲
「アドインの素」のソート関数呼び出し記述が簡単、処理速度が高速参照設定が必要配列自体のソートもインデックスの取得も可。オールマイティ、数万件でも大丈夫、1次元も2次元も可(自動判別)
安定化コムソート安定ソート、処理速度はそこそこ高速安定化した分コムソートより遅い並べ替えインデックスを返す2次元配列の並べ替え
コムソート呼び出し記述が簡単、処理速度はまあまあ高速安定ソートではない。2次元以上の配列には対応していない。配列自体を並べ替えて返す1次元配列の並べ替え
バブルソートアルゴリズムが簡単なのでカスタマイズしてプログラムへの組み込みが容易多量データには不向き安定ソート数十件程度のデータの並べ替え
あなたの自作クイックソートとにかく処理速度が超高速自分で作るのは面倒。データの並び方次第では激遅になるという致命的な欠点がある。安定ソートではない数万件以上のデータで高速な並べ替えが必要な時。但しデータはランダムであることが必須

※安定ソートとは:元々同じ値の順番について、並べ替え前と後でその順番が保たれるソートを「安定ソート」
といいます。同じ値なら順番が前か後ろかなんて関係ないのでは、と思われるかもしれませんがそうではありません。

例えば2次元の配列を並べ替える事を考えた時、2列用のソート関数、3列用のソート関数...などとすべての
ケース用に関数を用意しておくことは現実的ではありませんから、一般的には並べ替えインデックスを返す
関数を用意しておきます。

そして関数により得られたインデックスを使って各列を並べ替えます。この時例えば第1列をキーにしたとして
第1列に同値があった時、安定ソートでは2列目以降での順番が入れ替わることはありません。安定ソートでない
場合はその順番は不定になります。

もう少し言い方を変えると、安定ソートを使えば複数列で複数の並べ替えキーを使用した並べ替えが出来ますが
安定ソートでないとそれが出来ません。
top