• ベストアンサー

クイックソートの比較回数について

中央値をピボットとするクイックソートで、入力データ数が1024で昇順データの場合はO(nlogn)の関係より10240回の比較回数が得られる、というのは合っているでしょうか? ご回答お願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

O(nlogn)は、「正確に」nlognであるわけではなく、 そのオーダーであるということを言っているだけですので、 10240回でなくてもいっこうに差し支えないのではないでしょうか。

kaibasira1
質問者

お礼

そうだったのですか! 私はてっきりオーダーは回数が関係あるものかと思ってました。 ご回答ありがとうございます!

その他の回答 (2)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

>クイックソートのプログラムを作成し、比較回数を調べてみた そのソースコードを見せていただくことは可能ですか?

kaibasira1
質問者

お礼

以下が作成したものです。 #include <stdio.h> #include <stdlib.h> #include <time.h> #define MAX_DATA 1024 void Quick(int x[], int left , int right); void koukan(int x[],int i , int j); void showData(int x[],int n); int main(void); int k = 0; int h = 0; void Quick(int x[],int left,int right){ int i,j; int pivot; i = left; j = right; pivot = x[(left + right) / 2]; while (1) { while (x[i] < pivot){ h++; i++; } while(pivot < x[j]){ h++; j--; } if(i >= j) break; koukan(x,i,j); k++; } if(left < i - 1){ Quick(x,left,i - 1); } if(j + 1 < right){ Quick(x,j+1,right); } } void koukan(int x[],int i,int j) { int temp; temp = x[i]; x[i] = x[j]; x[j] = temp; } void showData(int x[],int n) { int i; for (i = 0; i < n;i++) printf("%d ",x[i]); printf("\n"); } int main(void){ int i; int x[MAX_DATA]; int n = MAX_DATA; for(i = 0;i < MAX_DATA;i++){ x[i] = i; } printf("ソート前:\n"); showData(x,n); printf("ソート中:\n"); Quick(x,0,n - 1); printf("ソート後:\n"); showData(x,n); printf("交換回数%d\n",k); printf("比較回数%d\n",h); return 0; }

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

比較回数を数えるためのサンプル・プログラムを書いてみてはいかがでしょうか。

kaibasira1
質問者

お礼

お答えありがとうございます。 実はクイックソートのプログラムを作成し、比較回数を調べてみたのですが、出てきた回数は8024回だったので不安になり質問した次第です。

関連するQ&A

  • クイックソート

    クイックソートの平均入れ替え回数っていくつになりますか? 全体の比較回数はnlognでしたっけ?

  • クイックソート

    クイックソートのアルゴリズムの問題で 9 1 8 5 3 4 2 6 7 と上記のようなデータ列を昇順に整列するときに 9 1 8 5 3 4 2 6 7 6 1 8 5 3 4 2 9 7 6 1 2 5 3 4 8 9 7 とここで詰まってしまうんですけどどうしたら昇順に導けますか?

  • バブル・ソート、クイック・ソート

    N個(N=4,5,6)のデータが全て等しいデータ列(例えばN個の数字全部が1のとき)をバブルソートで並び替えたとき、データの交換回数は何回か。また、同じデータ列をクイックソートで並び替えたときはどうか。 という問題があるのですが、どう比較するのかがわかりません。詳しい方、説明よろしくお願いします。

  • 比較回数が少なくなるソート

    大量にある画像に人間が優劣を判定し、その結果をソートしたいです。(順位を付けたい) 画像はすでにデジタルデータ化されてパソコンの中にあります。 二つの画像を人間に見せて判断を求める事を繰り返すプログラムを作成しようと思うのですが、人間が行う操作(比較の判断)をなるべく少なくする為には、どのようなソートのアルゴリズムを選択したら良いでしょうか? ソートのアルゴリズムの説明などを読むと、例えば、「バブルソート」及び「選択ソート」ではn(n-1)/2の比較が必要になるそうですが、この比較の回数が最も少ない方法を探しています。 また、例えばA,B,Cの比較に置いて、 A>B、B>Cの比較後にはAとCは比較せずともA>Cの関係が成り立つのですが、こういった事も考慮した上での比較回数の最も少ないソートの方法が知りたいです。 以上、ご指導のほど、よろしくお願い申し上げます。

  • シェルソート,クイックソート

    シェルソートは比較数が小さいとクイックソートよりも早いですが,なぜでしょうか?

  • アルゴリズムの問題なのですが、マージソートとクイックソートについて教え

    アルゴリズムの問題なのですが、マージソートとクイックソートについて教えてください。 数列の(21 99 38 22 15 6)をマージソートで並び変えて、クイックソートでも並び変えたいのです。 マージソートで並び変えた手順は (21 99 38 22 15 6) (下矢印) (21 99 38)(22 15 6) (下矢印) (21 99)(38)(22 15)(6) (下矢印) (21)(99)(38)(22)(15)(6) (下矢印) (21 99)(38)(15 22)(6) (下矢印) (21 38 99)(6 15 22) (下矢印) (6 15 21 22 38 99) となりました。 この時、分割回数と統合回数がともに5なのですが、どう見たら5回なのでしょうか。 分割回数は3で統合回数も3ではないのでしょうか? クイックソートの方なのですが、 回答は (21 99 38 22 15 6) (下矢印) (15 6)(21)(99 38 22) (下矢印) (6)(15)(21)(22 38)(99) (15と38にした場合) (下矢印) (6)(15)(21)(22)(38)(99) となっていて、 最も効率のよいピボットを選択した場合分割回数は3となっています。 私がやってみたところ (21 99 38 22 15 6) (下矢印) (15 6)(21)(99 38 22) (下矢印) (6)(15)(21)(22)(38)(99)  (15と38を選んだ) これではいけないのでしょうか。 長くなりましたが、よろしくお願いします。

  • バブルソートとクイックソート

    まだソートについて勉強し始めたばかりですが バブルソートは対象の総数が増えるとそれに伴い比較回数は増加するのに対し クイックソートはそれほど増加しないのはなぜでしょうか?? 検索してみてもプログラムが書いてあってよくわからないので... 根本的なところなのでしょうがどなたか教えてください!

  • クイックソートで並べ替え

    友人から情報処理の質問を受けました。ですが、私では良く分からなかったので質問します。 2,4,8,1,6,5,2,7,3,7の整数をクイックソートで並べ替えよ。 また、比較回数を示せ(軸要素は先頭の2要素のうち大きいほうとせよ)。 よろしくお願いします。

  • クイックソートの交換回数

    クイックソートを行うプログラムを書いています。 これを、比較回数と交換回数を表示できるように改良したいのですが、うまくいきません。カウントする場所は間違えてないと思うのですが、出力の場所が悪いせいか、大量の出力結果が表示されます。 うまく表示させる方法を教えてください。 ~time.c~ #include <stdio.h> #include <stdlib.h> #include <time.h> #include "sfmt.h" #define MAX 5000 void quick_sort(int a[], int start, int end); main() { int i , x[MAX] , n; time_t start , end ; int sn; printf("適当な数字の入力 : "); scanf("%d", sn); init_gen_rand(sn); for(i=0; i<MAX; i++) x[i]= (gen_rand32()% MAX);; n=MAX; start = clock(); //測定対象プログラム quick_sort(x, 0, n-1); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("実行時間: %f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~quick.c~ #include <stdio.h> int hikaku = 0, koukan = 0; int divide_array(int x[], int start, int end) { int i, j, tmp; i = start; j = end -1; while(1){ while(x[i] < x[end])i++; hikaku++; //比較カウント while(x[j] > x[end] && j>i)j--; hikaku++; //比較カウント if(i >= j) break; tmp = x[i]; x[i] = x[j]; x[j] = tmp; koukan++; //交換カウント i++; j--; } tmp = x[i]; x[i] = x[end]; x[end] = tmp; printf("比較回数: %d\n", hikaku); printf("交換回数: %d\n", koukan); return i; } ~quick2.c~ int divide_array(int x[], int start, int end); void quick_sort(int a[], int start, int end); void quick_sort(int a[], int start, int end) { int s; if(start >= end) return; s = divide_array(a, start, end); quick_sort(a, start, s-1); quick_sort(a, s+1, end); }

  • クイックソートの比較交換回数について

    クイックソートの比較交換回数を変数countで計算し、表示させようとしているのですがうまくいきません。 改善策を教えていただけないでしょうか。 /* クイックソート */ void quickSort(randomlist_t data[],int n){ /* 実質的な処理は何もせず、クイックソートを実際に行う関数を呼び出すのみ */ int count = 0; quickSort_1(data,0,n-1,count); printf("count:%d\n",count); } /* 実際にクイックソートを行う関数 */ void quickSort_1(randomlist_t data[],int l,int r,int count){ int v; if(l >= r) /* 整列する要素が1つなら、何もしないでリターンする */ return; v = partition(data,l,r,count); /* 枢軸vを基準に分割する */ quickSort_1(data,l,v-1,count); /* 左の部分の配列a[l]~a[v-1]を整列する */ quickSort_1(data,v+1,r,count); /* 右の部分の配列a[v+1]~a[r]を整列する */ } /* 配列a[l]~a[r]を分割する。枢軸の添え字を返す */ int partition(randomlist_t data[],int l,int r,int count){ int i,j,pivot; randomlist_t t; i = l - 1; j = r; /* ポインタiとjを初期化する */ pivot = data[r].no; /* 一番右端の要素を枢軸にする */ for(;;){ /* ポインタiとjとがぶつかるまで繰り返す */ while(data[++i].no < pivot) count++; /* ポインタiを右へ進める */ while(i < --j && pivot < data[j].no) count++; /* ポインタjを左へ進める */ if(i >= j) break; /* ポインタiとjがぶつかったらループを抜ける */ t = data[i]; data[i] = data[j], data[j] = t; /* iの指す要素とjの指す要素を交換する */ count++; } t = data[i]; data[i] = data[r]; data[r] = t; /* a[i]と枢軸を交換する */ count++; return i; }

専門家に質問してみよう