• ベストアンサー

クイックソート

クイックソートのプログラムを作ったのですがうまくいきません 汗 コンパイル時に sample1.c: In function ‘quicksort’: sample1.c:31: error: expected expression before ‘]’ token sample1.c:32: error: expected expression before ‘]’ token sample1.c:32: error: too few arguments to function ‘quicksort’ とでます。 まだアルゴリズムやCは勉強始めたばかりで基本的なところでつまって いるかもしれません。ご教授おねがいします。 /*クイックソート*/ #include<stdio.h> #define MAXDATA 10 #define swap(type,a,b) {type m; m = a; a = b; b = m;} void quicksort(int a[],int left ,int right) { int i,j,pivot; pivot = a[left]; i = left + 1; j = right; while(i <= j){ while(a[i]<pivot) i++; while(a[j]>pivot) j--; if(i<j){ swap(int,a[i],a[j]); i++; j--; } } swap(int,a[left],a[j]); quicksort(a[],left,j-1); quicksort(a[],j+1,right); } int main(void) { int k,j,sort[MAXDATA]; for(k=0;k < MAXDATA;k++) {printf("sort[%d]:",k); scanf("%d",&sort[k]);} for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); puts("ソートしますか? Yes:1 No:0 ///"); scanf("%d",&j); if(j==1){ quicksort(sort,0,MAXDATA-1); for(k=0;k < MAXDATA;k++) printf("%3d",sort[k]); } putchar('\n'); return(0); }

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

  • ベストアンサー
  • hashioogi
  • ベストアンサー率25% (102/404)
回答No.3

今現在質問者のプログラムがどの程度修正されているのか分かりませんが、提示されているプログラムを拝見する限り、いくつかバグがあるように感じます。 一点だけ申し上げますと、通常、再帰関数を作成する場合内部処理が2つ必要だと感じます。 例えば階乗の値を求めるプログラムが再帰関数の例としてよく取り上げられます。階乗の計算というのは5!=5×4×3×2×1というものです。 プログラムの例は、以下のようになります。 #include<stdio.h> int kaijou (int n) { if (n == 1) { /* 内部処理1 */ return 1 ; } else { /* 内部処理2 */ return n * kaijou (n - 1) ; } } int main(int argc, char* argv[]) { printf ("%d\n", kaijou (5)) ; return(0); } 質問者のプログラムは内部処理2しかないように思われます。 この場合、内部処理2しかないと5×4×3×2×1×0×(-1)×(-2)×(-3)×…といつまでたっても終わらなくなるように思いますが(実際にはそのうちにスタックがパンクしてエラーになるでしょうけど)。

Nya-22
質問者

お礼

No.2さんがいわれているようなもので止めようと思います。 返答送れてすみません。ありがとうございました。

その他の回答 (2)

回答No.2

未検討: quicksortに if (left + 1 > right){ return ; } 見たいなのがないと止まらないいんじゃないかな?これ。

Nya-22
質問者

お礼

返答送れてすみません。 再帰が止まらないですね 汗。何とか頑張って作ってみます。 ありがとうございました。

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

>quicksort(sort,0,MAXDATA-1); ここではエラーが出ていないのに >quicksort(a[],left,j-1); >quicksort(a[],j+1,right); ここではエラーが出ていますね。 両者の違いをよく見比べてください。

Nya-22
質問者

お礼

あーわかりました。ただa[]をaでいれてコンパイルは 通ったのですが、 今度はセグメントエラーとなってしまいました。 もし原因がわかりましたら教えてください。

関連するQ&A

  • クイックソートについて

    クイックソートのプログラムなんですが、 セグメンテーション違反で実行出来ません。 どこがおかしいのでしょうか? int main(void) { FILE *fp; int a[10],b=0,n; clock_t start; double jikan; if( (fp = fopen ("quicksort.txt","r") ) == NULL ) { printf("ファイルが見つかりません : quicksort.txt\n"); exit(1); } while( fscanf(fp, "%d", &a[b]) != EOF ) { b++; } start = clock(); quick_sort(a,n); jikan = clock() - start; for(n = 0; n < b ; ++n) { printf("%d ",a[n]); } printf("計算時間 %.3f 秒 \n", jikan/CLOCKS_PER_SEC); return 0; } int partition(int a[], int l, int r) { int i,j,pivot,t; i = l-1; j = r; pivot = a[r]; for(;;) { while( a[++i] < pivot ) ; while( i < --j && pivot < a[j] ) ; if( i >= j ) break; t=a[i]; a[i]=a[j]; a[j]=t; } t=a[i]; a[i]=a[r];a[r]=t; return i; } void quick_sort_1(int a[],int l,int r) { int v; if( l >= r ) return; v = partition( a, l, r); if( l < v-1 ) quick_sort_1( a, l, v-1); if( v+1 < r ) quick_sort_1( a, v+1, r); } void quick_sort(int a[],int n) { quick_sort_1( a, 0, n-1); }

  • クイックソート

    今クイックソートのプログラム作成をしていますが、分からない箇所が幾つかあります。下は、作成した時のプログラムリストです。 class QuickSort{ static int compare = 0;   static int copy = 0;    static int swap = 0; static void swap(int a[], int i, int j){    int tmp; tmp = a[i];copy++; a[i] = a[j];copy++; a[j] = tmp;copy++; swap++;} static void showArray(int a[], int l, int r){//配列の内容を表示するメソッドで、動作:部分配列a[l]~a[r]の要素を表示。これが分かりません。     int a[l] = {1,2,3,4,5,6,7,8,9,10}; int a[r] = {11,12,13,14,15,16,17,18,19,20};} static void initArray(int a[], int N){ int i;     a[0]=0; for(i=1;i<N;i++) a[i] = i; for(i=1;i<N;i++){ int j,k; j = (int)(java.lang.Math.random()*(N-1)) + 1; k = (int)(java.lang.Math.random()*(N-1)) + 1; swap(a,j,k);}} public static void (int a[],int l, int r) { if (r+1-l <= 1) return; int e = (l+r+1)/2; int c = 0; return a[c]; } static int partition(int a[], int l, int r, int pivot){// 配列の分割を行うメソッドです。そのあと分割に要した比較回数(=iの増加分+jの減少分)を変数compareに加算し、iの値を戻り値として返さないといけませんが、そこんとこが分かりません。 while (true) { while (a[l] < pivot) l = l + 1; while (a[r] >= pivot) r = r - 1; if (l > r) return l; swap(a, l, r); } } static void swap(int[] a, int i, int j) { int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } } int i=0; int j=0; return i; } static void quicksort(int[] a, int l, int r){//(カットオフなしで)再帰的にクイックソートを行うメソッドです。paritionメソッドを用い、a[l]~a[r]を分割値a[r]で分割するのが条件ですが、ここも全然分かりません。 if(l < r){ int i = l; int j = r; int x = a[(i+j)/2]; do{ while(a[i]<x) i++; while(a[j]>x) j--; if(i<=j) { swap(a,i,j); i++; j--; } }while(i<=j); quickort(a,l,j); quicksort(a,i,r); } } static void swap(int[] a, int s, int t){ int temp = a[s]; a[s] = a[t]; a[t] = temp; return; int i,pivot; } public static void main(String args[]){ //上で作ったメソッドを用いて、ソート過程を表示しながらクイックソートを実行 //手順は次のようになる。     1.要素を(20個もつ)整数型配列aを宣言     2.整数型変数Nに配列aの要素数を保存     3.initArrayメソッドを用いて配列aを初期化 4.showArrayメソッドを用いてソート前の配列aの内容を表示 5.変数compare,copyの値を0に初期化 6.quickSortメソッドを用いて配列aを選択ソート     7.showArrayメソッドを用いてソート後の配列aの内容を表示 8.ソートにかかった比較・コピーの回数を表示 //これも分かりません。 } 分かる人がいましたら教えて下さい。お願いします。

  • クイックソートプログラムでセグメンテーション違反がでるのですが

    クイックソートのプログラムを作成したのですが、 実行するとセグメンテーション違反が発生して、上手くいきません。何処に原因があるのでしょうか? また、セグメンテーションン違反とはどういったころなのでしょうか? アドバイス宜しくお願いします。 #include <stdio.h> int quick_sort(int *a,int start,int end); int partition(int *a,int start,int end); main() { int n; int a[n]; int i; printf("ソートしたい要素の個数は?\n"); scanf("%d",&n); for(i=0;i<=n-1;i++) a[i]=0; for(i=0;i<=n-1;i++){ printf("%dのデータを入力してください。\n",i+1); scanf("%d",&a[i]); } printf("ソート前のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); quick_sort(*a,1,n-1); printf("ソート後のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); } int quick_sort(int *a,int start,int end) { int pivot; if(end-start>0){ pivot=partition(a,start,end); quick_sort(a,start,pivot-1); quick_sort(a,pivot+1,end); } } int partition(int *a,int start,int end) { int i,j,pivot,tmp; i=start-1; j=end; pivot=a[end]; while(1){ while(a[++i]<pivot); while(i<--j && a[j]>pivot); if(i>=j) break; tmp=a[i]; a[i]=a[j]; a[j]=tmp; } a[end]=a[i]; a[i]=pivot; return i; }

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

    http://www1.cts.ne.jp/~clab/hsample/Sort/Sort9.html こちらにあったソースを改造しました。 #include <stdio.h> void QSort(int x[ ], int left, int right) {   int i, j, temp;   int pivot;   i = left;   j = right;   pivot = x[(left + right) / 2]; // 6,5,4,3 // pivot=4   while (1) {   while (x[i] <= pivot) i++; // サイトのソースは = が無かったから付けた // 2回目のループでは j=2   while (pivot < x[j]) j--; // 2回目のループで x[-1] を参照しませんか? // 初回ループで i=0, j=3   if (i >= j) break;   temp = x[i]; x[i] = x[j]; x[j] = temp; // 交換   i++; j--;   }   ShowData(x, 10); // 途中経過を表示   if (left < i - 1) QSort(x, left, i - 1);   if (j + 1 < right) QSort(x, j + 1, right); } void ShowData(int x[ ], int n) {   int i;   for (i = 0; i < n ; i++) printf("%d ", x[i]);   printf("\n"); } void main(void) {   int x[] = {6, 3, 1, 7, 0, 4, 8, 5, 2, 9};   int n = 10;   printf("ソート前:\n");   ShowData(x, n);   printf("ソート中:\n");   QSort(x, 0, n - 1);   printf("ソート後:\n");   ShowData(x, n); } テストデータが 6,5,4,3 だと、 2回目のループで x[-1] を参照しませんか? 今コンパイラが使えません。 教えてください。 それと、=を付けたんですが、付けないといけませんよね?

  • クイックソート後の出力(pascal)

    20個の整数データをクイックソートして出力せよ、という課題が出ました。クイックソートまでは出来た(コンパイルできたのでおそらく)のですが、その順に出力する方法がわかりません。どなたかお教えください。 program sort(input,output); const n = 20; type index = 1..n; var A : array[1..n] of integer; i,x,a : integer; p,j,k : index; function PIVOT(i,j : index):integer; var k:index; begin k:=i+1; while (A[i]=A[k]) and (k<=j) do k:=k+1; if k>j then PIVOT:=0 else if A[i]>=A[k] then PIVOT:=i else PIVOT:=k end; procedure SWAP(var x,y:integer); var temp:integer; begin temp:=x; x:=y; y:=temp end; procedure PARTITION(i,j:index; a:integer; var k:index); var l,r:index; begin l:=i; r:=j; while A[l]<a do l:=l+1; while A[r]>=a do r:=r-1; while l<=r do begin SWAP(A[l],A[r]); l:=l+1; r:=r-1; while A[l]<a do l:=l+1; while A[r]>=a do r:=r-1; end; k:=l end; procedure QUICKSORT(i,j:index); var a:integer; p:index; k:index; begin p:=PIVOT(i,j); if p<>0 then begin a:=A[p]; PARTITION(i,j,a,k); QUICKSORT(i,k-1); QUICKSORT(k,j) end end; begin i:=0; i:=1+1; for i:= 1 to n do begin A[i]:=0; end; i:=0; i:=i+1; for i:= 1 to n do begin readln(x); A[i]:=x end; a:=PIVOT(p,j); PARTITION(p,j,A[a],k); QUICKSORT(p,j) end. QUICKSORT(p,j)とend. の間に出力方法を書き込みたいのです。

  • クイックソートの解説頂けないでしょうか。

    C言語を始めたばかりのプログラマ見習いです。 クイックソートのトレースでつまっています。 下記プログラムにあたっているのですが、 どなたか解説頂けないでしょうか。 void q_sort(int d[],int left,int right) { int i=left; int j=right; int t; t=d[(i+j)/2]; while(i<j){ for(;t>d[i];i++) ; for(;t<d[j];j--) ; if(i<=j){ /*Swap*/ int t; t=d[i]; d[i]=d[j]; d[j]=t; i++; j--; } } if(left<j){ q_sort(d,left,j); } if(){ q_sort(d,i,right); } } 長い引用で申し訳ありません。 クイックソートの理論的な部分は理解しているつもりです (最初に基準値を置き、それより大きいもしくは小さい 値を左右に振り分ける→分割統治法で繰り返し、最終的に 値がソートされた状態になる)。 よく判らないのがwhile文の中、特に最初のfor文の 役割です。初期値が空文で、中身もなし・・・この文は なにをしているのでしょうか? ネット上で解説されているソースをのぞいてみましたが 少し形が違っていたので、できればこのプログラムを もとにアドバイス頂けないでしょうか。 それ以外の回答(参考URL等)でも嬉しいです。 どうぞ宜しくお願いします

  • クイックソートのプログラムを実行するとエラーが出る

    プログラミング初心者のものです。 ソースのファイル名はquicksortという名前にして、コンパイル&実行すると、 「Quicksortが原因でQUICKSORT.EXEにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と、 「Quicksortが原因でKERNEL32.DLLにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と言うエラーが出てきて最後まで実行されません。 どうしてでしょうか?ちなみにソースは以下のものです。 #include<stdio.h> #define N 10 void quicksort(int a[],int first,int last) { int i,j,p,w,k; k=(first+last)/2; p=a[k]; i=first; j=last; while(i<=j){ while(a[i]<p){ i++; } while(a[j]>p){ j--; } w=a[i]; a[i]=a[j]; a[j]=w; i++; j--; } if(first>j){ quicksort(a,first,j); } if(last>i){ quicksort(a,i,last); } } main() { int a[]={18,97,59,72,5,38,11,43,67,26}; int i; printf("Before:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); quicksort(a,0,N-1); printf("After:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); return(0); }

  • クイックソートをC++で作りたいのですが・・・

    題の通り、C++でクイックソートを作りたいのですが、以下のコードではセグメンテーションエラーで動きませんでした。partition関数があやしいと思い、色々と試してみたのですが、やはりできなかったので、質問させていただくことにしました。 結果としては、print関数で昇順に表示出来ればいいのですが・・・。 以下のコードのどこをどう変えれば良いのか、ご指摘の方、何卒よろしくお願い致します。 #include <iostream> #include <vector> using namespace std; class Array { private: vector<int> array; public: void insert( int value ){ array.push_back( value ); } int getSize( ){ return (int)array.size( ); } void quick_sort( ){ quick_sort( 0, (int)array.size( ) - 1 ); } void quick_sort( int left, int right ); int partition( int left, int right ); void swap(int *a,int *b){int tmp=*a;*a=*b;*b=tmp;} void print( ); }; // クイックソートにより配列の添字 left ~ right の部分を整列する関数 void Array::quick_sort( int left, int right ) { if ( left >= right ) { return; } int v = partition( left, right ); quick_sort( left, v - 1 ); quick_sort( v + 1, right ); } //この関数を考える // 配列の添字 left ~ right の部分を,pivot の値より小さい要素と,大きい要素に分割し pivot の位置を返す関数 int Array::partition( int left, int right ) { int i=left; //左からの処理位置 int j=right; //右からの処理位置 int pivot=array[(int)(left+right)/2]; //基準 int tmp=0; while(true){ while(array[i]<pivot){i++;} while(array[j]>pivot){j--;} if(i>=j){return i;} tmp=array[i]; array[i]=array[j]; array[j]=tmp; i++; j++; } } // 配列の内容を表示する関数 void Array::print( ) { for ( int i = 0; i < (int)array.size( ); i++ ) { cout << array[i] << " "; } cout << endl; } int main( ) { Array a1; a1.insert( 56 ); a1.insert( 34 ); a1.insert( 57 ); a1.insert( 64 ); a1.insert( 3 ); a1.insert( 87 ); a1.insert( 85 ); a1.insert( 37 ); a1.insert( 21 ); a1.insert( 4 ); a1.insert( 68 ); a1.insert( 62 ); a1.insert( 42 ); a1.insert( 55 ); a1.insert( 63 ); a1.insert( 95 ); a1.insert( 7 ); a1.insert( 32 ); a1.insert( 78 ); a1.insert( 11 ); cout << "要素数: " << a1.getSize( ) << endl; cout << "ソート前: "; a1.print( ); a1.quick_sort( ); // ここで,ソートを行う関数を呼び出す cout << "ソート後: "; a1.print( ); return 0; }

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

    クイックソートの比較交換回数を変数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; }

  • クイックソート キー比較回数をカウント

    クイックソートでキー比較回数をカウントする。 以下のように書いたのですが、 22行目(C++;)の状態ではまだ何かが足りないらしいのですが、何が足りないのか教えてください。 /* ここからプログラム */ #include <stdio.h> #define N 10 /* 配列aの要素数 */ static int a[N] = { 7, 20, 1, 18, 9, 15, 24, 10, 3, 12}; int main() { __int i, j; /* ループカウンタ */ __int temp; /* 交換用 */ __int pivot; /* 基準値 */ __int C = 0; /* キー比較回数C */ __int M = 0; /* データ置換回数M */ __i = 0; /* iを先頭要素番号 */ __j = N - 1; /* jを末尾要素番号 */ __pivot = a[j / 2]; /* 任意の要素を取り出し基準値 */ __while (i <= j){ ____C++; /* 22行目,キー比較回数カウント */ ____while (a[i] < pivot) /* a[i] >= pivot が見つかるまで */ ______i++; /* iを増加 */ ____while (a[j] > pivot) /* a[j] <= pivot が見つかるまで */ ______j--; /* jを減少 */ ____if (i < j && a[i] != a[j]) { /* i < j かつ a[i]≠a[j] ならば */ ______temp = a[i]; /* a[i]とa[j]を交換 */ ______a[i] = a[j]; ______a[j] = temp; ______M++; /* データ置換回数回数カウント */ ______i++; /* iを増加 */ ______j--; /* jを減少 */ ____} ____if (i == j || a[i] == a[j]){ /* i = j かつ a[i] = a[j] ならば */ ______i++; /* iを増加 */ ______j--; /* jを減少 */ ____} __} /* ここから結果表示 */ __for (i = 0; i < N; i++) ____printf("%3d ", a[i]); __printf("\n"); __printf(" キー比較回数 : %3d回\n データ置換回数: %3d回\n", C, M); /* ここまで結果表示 */ __return 0; } /* ここまでプログラム */

専門家に質問してみよう