みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

qsortの動作

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

qsortの動作

投稿記事 by みけCAT » 13年前

いつもお世話になっている(?)C言語標準関数、qsort。
前回の情報オリンピックでも、なんと2回も使ってしまいました。
でも、いったいどんな処理をしているのだろうか?
そう思ったことはありませんか?
(え?ない?別にいいですよ。個人の勝手です。)
そこで、どのような比較や交換をしているかを、比較関数に細工をして調べてみました。
まずはコンソールアプリケーションで実験。
► スポイラーを表示
※ここのシステムに不都合があるようです。'は半角の’に置き換えてください。

実行結果の一例(15を入力)
► スポイラーを表示
|の左側が現在の配列の内容、右が何と何を比較しているかです。
比較は左にあるものが一つ目の引数、右にあるものが二つ目の引数として渡されています。
・・・少しわかりにくいですね。
そこで、DXライブラリを使ってわかりやすく表示してみました。
プログラムとソースコードは添付してあります。
これでだいぶ見やすくなりました。
赤くなっている数字が比較関数に渡された一つ目の引数、緑になっている数字が二つ目の引数です。
並べ替えの様子がアニメーションされます。
このプログラムを観察したところ、(自分の環境では)次のような動作をしていることがわかりました。

CODE:

・注目している部分の要素数が9以上の時
 クイックソートを行う。
 ・まず、一番左、真ん中、一番右の要素を昇順に並べ替える。
 ・並べ替えた真ん中の要素をピポットとする。
 ・左から順番にピポットと比較する。
 ・ピポットを超える数字があったら次へ。それまで順番に比較する。
 ・右から順番にピポットと比較する。
 ・ピポット未満の数字があったら、
  ・左のピポットを超える数字と右のピポット未満の数字を入れ替える。
  ・左右それぞれ、入れ替えた次の数字からこの動作を繰り返す。
 ・ピポット自体とは比較しない。飛ばす。
 ・左からの比較場所が右からの比較場所かそれより右になったら、
  ・その場所で左右にわけて全体の処理をそれぞれ行う。
・注目している部分の要素数が8以下の時
 ・左から、そこまでの最大値とそこの値を比較する。
 ・一番右まで比較が済んだら、最大値と一番右の値を入れ替える。
 ・次に、右から二番目までこの処理を行う。
 ・最初の二つになるまで繰り返す。
・・・説明が下手だな。誰かもっとうまく解説してください。
まあ、百聞は一見に如かず。是非このプログラムを実際に動かして、自分の目で確かめてください。

追記
Ideoneやcodepadではどうやらマージソートのようです。
http://ideone.com/ICcZJ
http://codepad.org/EfXuv8pJ
添付ファイル

[拡張子 zip は無効化されているため、表示できません]

最後に編集したユーザー みけCAT on 2011年12月21日(水) 18:23 [ 編集 1 回目 ]
理由: Ideoneとcodepadでの実験を追記

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前

Re: qsortの動作

投稿記事 by h2so5 » 13年前

最後に編集したユーザー h2so5 on 2011年12月21日(水) 18:16 [ 編集 1 回目 ]