• ベストアンサー

選択法(selection sort)について

選択法について質問させていただきます。 選択法で基準値(pivot)を使用し、K番目に小さい要素を見つけるプログラムを作成しています。以下は私が作成したプログラムですが、 行き詰まってしまいました。どなたか教えていただけないでしょうか?ちなみに学校の宿題で引数は変えれない状態です。 #include<stdio.h> int selection(int low,int high,int k){ int pivotpoint; int s[]={27,10,12,20,25,13,15,22}; if(low==high) return s[low]; else{ partition(low,high,pivotpoint); if(k==pivotpoint) return s[pivotpoint]; else if(k<pivotpoint) return selection(low,pivotpoint-1,k); else return selection(pivotpoint+1,high, k); } } void partition(int low,int high,int pivotpoint){ int i,j; int pivotitem; int tmp; int s[]={27,10,12,20,25,13,15,22}; pivotitem=s[low]; j=low; for(i=low+1;i<=high;i++){ if(s[i]<pivotitem){ j++; tmp=s[i]; s[i]=s[j]; s[j]=tmp; } } pivotpoint=j; tmp=s[low]; s[pivotpoint]=s[low]; s[low]=tmp; } main(){ int num; int s[]={27,10,12,20,25,13,15,22}; num=selection(0,7,3); printf("the third number is %d?n", num); } エラーメッセージ selection.c:20: error: conflicting types for 'partition' selection.c:10: error: previous implicit declaration of 'partition' was here

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

>引数で検索する配列を示す事ができない場合 グローバルな変数にするしかないと思います。

ken6791
質問者

お礼

BLUEPIXYさんありがとうございました。 教えていただいた通りやってみます。

その他の回答 (1)

  • keikan
  • ベストアンサー率42% (75/176)
回答No.1

プロトタイプ宣言がない状態で、 partition関数がselection関数から呼ばれています。 プロトタイプ宣言しないのであれば、関数の位置を入れ替えて、実際に使われる前に関数が構築されるようにしましょう。

ken6791
質問者

お礼

keikanさん、貴重なご意見ありがとうございました。

ken6791
質問者

補足

引数で検索する配列を示す事ができない場合、どのようにすればpartition関数やselection関数でその配列を認識させる事ができるでしょうか? 私の場合partition,selection両関数の中に検索したい配列を書く事しか考えつきませんでした。 もっといい方法があるような気がしております。 よろしく御願いいたします。

関連するQ&A

  • 選択ソートアルゴリズム(selection sort)について 質問No.1226692のつづき

    BLUEPIXYさん、keikanさんありがとうございました。せっかく教えていただいたのですが、セグメンテーションエラーが出てしまいます。 選択法で基準値(pivot)を使用し、K番目に小さい要素を見つけるプログラムを作成しようとしています。しかし、コンパイル時にセグメンテーションフォルトメッセージが出力されるのですが、どこが間違っているのかわからず、途方にくれています。どなたか教えていただきたく。よろしく御願いいたします。 #include<stdio.h> int s[100]={27,10,12,20,25,13,15,22}; int pivotpoint; int selection(int, int, int); //void partition(int, int, int); main(){ int num; num=selection(0,7,3); printf("The third smallest is %d?n ", num); } int selection(int low,int high,int k) { void partition(int, int, int); //int pivotpoint; if(low==high) return s[low]; else{ partition(low,high,pivotpoint); if(k==pivotpoint) return s[pivotpoint]; else if(k<pivotpoint) return selection(low,pivotpoint-1,k); else return selection(pivotpoint+1,high, k); } } void partition(int low,int high,int pivotpoint) { int i,j; int pivotitem; int tmp; pivotitem=s[low]; j=low; for(i=low+1;i<=high;i++){ if(s[i]<pivotitem){ j++; tmp=s[i]; s[i]=s[j]; s[j]=tmp; } } pivotpoint=j; tmp=s[low]; s[pivotpoint]=s[low]; s[low]=tmp; }

  • 基準値をランダムに選んでの選択ソート

    配列要素から基準値(pivot)をランダムに選び、K番目に小さい要素を検索するプログラムを書いているのですが、うまくいきません。かなり考えているのですが、何が間違っているのか全然わかりません。どなたか教えていただけないでしょうか? #include<stdio.h> #include<stdlib.h> #include<time.h> int pivotpoint; void partition3(int *s,int low,int high,int *pivotpoint) { int i,j,randspot; int tmp; int pivotitem; randspot=rand()%(high+1); pivotitem=s[randspot]; j=low; for(i=low+1;i<=high;i++){ if(s[i]<pivotitem){ j++; tmp=s[i]; s[i]=s[j]; s[j]=tmp; } } *pivotpoint=j; tmp=s[low]; s[low]=s[*pivotpoint]; s[*pivotpoint]=tmp; } int selection3(int *s,int low,int high,int k) { if(low==high) return s[low]; else{ partition3(s,low,high,&pivotpoint); if(k==pivotpoint) return s[pivotpoint]; else if(k<pivotpoint) return selection3(s,low,pivotpoint-1,k); else return selection3(s,pivotpoint+1,high,k); } } main() { int num,i,k; int high; int low=0; int s[1000]; struct timeval t1,t2; int seed=2; printf("How many elements?:"); scanf("%d",&high); printf("?n"); printf("What is the kth smallest number?:"); scanf("%d",&k); printf("?n"); srand(seed); for(i=0;i<high;i++){ s[i]=rand(); printf("%d ",s[i]); } printf("?n"); gettimeofday(&t1,0); num=selection3(s,low,high-1,k-1); gettimeofday(&t2,0); printf("Time=%dmicrosec?n", t2.tv_usec-t1.tv_usec); printf("The %dth smallest is %d?n ", k,num); }

  • 中央値(median)を使用しての選択法(selection sort)

    中央値(median)を使用して、選択法により、K番目に小さい要素を見つけるプログラムを作成しようとしていますが、なかなかうまくいかず困っています。どなたか助けていただきたく。以下は作成しましたプログラムです。質問内容欄に入りきらない所は補足に掲載しますのでよろしく御願いいたします。 #include<stdio.h> #include<stdlib.h> #include<time.h> //int pivotpoint; int minimum(int i, int j) { if(i<=j) return i; else return j; } void partition2(int *s, int low, int high, int *pivotpoint) { const int arraysize = high-low+1; const int r=(arraysize/5)+1; int i,j,mark,first,last; int pivotitem; int t[5]; int x,y,tmp; //t=(int *)malloc(5); for(i=1;i<=r;i++){ first=low+5*i-5; last=minimum(low+5*i-1,arraysize); for(x=first;x<last;x++){ for(y=x+1;y<=last;y++){ if(s[x]>s[y]){ tmp=s[x]; s[x]=s[y]; s[y]=tmp; } } } t[i]=s[first+2]; } pivotitem=select(r,t,(r+1)/2); j=low; for(i=low;i<=high;i++) if(s[i]==pivotitem){ tmp=s[i]; s[i]=s[j]; s[j]=tmp; mark=j; j++; } else if(s[i]<pivotitem){ tmp=s[i]; s[i]=s[j]; s[j]=tmp; j++; } *pivotpoint=j-1; tmp=s[mark]; s[mark]=s[j-1]; s[j-1]=tmp; } int selection2(int *s,int low,int high,int k) { int pivotpoint; if(high==low) return s[low]; else{ partition2(s,low,high,&pivotpoint); if(k==pivotpoint) return s[pivotpoint]; else if(k<pivotpoint) return selection2(s,low, pivotpoint-1,k);

  • マージソートについて

    マージソートの要素の比較と交換回数を計測するプログラムを作っているのですが、マージのどの段階が交換処理になるのかが分からず困っています。 マージ処理の実行回数をカウントする配列sを設けて処理をカウントする場合、以下のプログラムだとどのタイミングでカウントすればよいでしょうか? ちなみに配列aは初めに値を割り振った配列で、配列bは別途で用意した作業用配列です。 最後のfor文やif文付近で配列の値を変化させて計測してみたのですが、計算量に合った動きをしてくれませんorz void merge_sort(int a[], int low, int high){ int mid, i, j, k; if(low >= high) return; mid = (low + high)/2; merge_sort(a, low, mid); merge_sort(a, mid+1, high); for(i = low; i <= mid; i++) b[i] = a[i]; for(i = mid+1, j=high; i <= high; i++, j--) b[i] = a[j]; i = low; j = high; for(k = low; k <= high; k++){ if(b[i] <= b[j]){ a[k] = b [i++]; } else{ a[k] = b[j--]; } } }

  • 選択ソートについて

    ------------------------------------- #include<stdio.h> int main(void) { int min,s,t,i,j; int num[]={5,6,4,9,2}; for(i=0;i<4;i++){ min=num[i]; s=i;        ////◎1 for(j=i+1;j<5;j++){ if(num[j]<min){ min=num[j]; s=j; } } t=num[i]; num[i]=num[s]; num[s]=t; } for(i=0;i<5;i++){ printf("%d ",num[i]); } putchar('\n'); return 0; } -------------------------------------- 以上のプログラムで◎1の記述が無くても正常にソートしてくれたので疑問に思いました。 「s=i;」が無い場合、最初のループのif文で、 if(num[j]<min){ min=num[j]; s=j; } 「6<5」を比べる時、条件に見合わないので、sに何も代入されず、 t=num[i]; num[i]=num[s]; num[s]=t; 以上の記述で、sが初期化されてないので、その時点のエラーが出ると思ったんですが、出ないで正常に動きました。 何故なのか教えてもらえると嬉しいです。

  • クイックソート

    振り仮名でソートをしたいのですが不等号の「<」など記号など混ぜた時にうまくソートされません。 ロジック的に問題があると思うのですが、平仮名や全角カタカナはソートされてるのです。以下のソースなのですが分かる方ご指摘頂ければ幸いです。 int lo0は固定で0 int hi0は検索結果の数-1となっております。 getKana()は振り仮名をbeanから取得しています。 private void QuickSort(Vector beanValues, int lo0, int hi0) { int low = lo0; int high = hi0; String mid; Object[] records = beanValues.toArray(); if (hi0 > lo0) { mid = ((Bean)records[ ( lo0 + hi0 ) / 2 ]).getKana(); while( low <= high ) { while ((low < hi0) && (((Bean)records[low]).getKana().compareTo(mid) < 0)) { ++low; } while ((high > lo0) && (((Bean)records[high]).getKana().compareTo(mid) > 0)) { --high; } if (low <= high) { swap(beanValues, low, high); ++low; --high; } } if (lo0 < high) QuickSort(beanValues, lo0, high); if (low < hi0) QuickSort(beanValues, low, hi0); } } private void swap(Vector records, int i, int j) { Object T = records.elementAt(i); records.setElementAt(records.elementAt(j), i); records.setElementAt(T, j); } }

  • マージソート内の再帰処理にすいて

    #include<stdio.h> #define MAX 4 int temp[MAX]; void marge(int num[],int left,int right) { int i,j,mid,k   if(left>=right)return; mid=(left+right)/2; marge(num,left,mid);//(1) maege(num,mid+1,right);//(2) for(i=left;i<=mid;i++) temp[i]=num[i]; for(i=mid+1,j=right;i<=right;i++,j--) temp[i]=num]j]; i=left; j=right; for(k=left;k<=right;k++) if(temp[i]<=temp[j]) num[k]=temp[i++]; else num[k]=temp[j--] } マージソート内はこういった関数を記述してエラーもでないのですが、(1)と(2)の処理がよくわかりません。 (1)は再帰的に処理していってif(left>=right)return;の条件を満たした場合に(2)の処理に入っていきますよね? その場合、(2)の処理を行う際に(1)が(2)の再帰より前に記述されているので(1)がまた処理されるのでしょうか? 一連の流れを(1)、(2)を使って表してほしいです。

  • ヒープソート

    何回も申し訳ございません。ヒープソートを使用して、K番目に小さい配列の要素を見つけるプログラムを作成していますが、セグメンテーションフォルトが出力され、途方に暮れています。どなたか助けていただけないでしょうか? #include<stdio.h> #include<stdlib.h> #include<time.h> void heap(int c,int size,int *s){ int child,p; int tmp; child=s[c]; while(1){ p=(c-1)/2;//calculate an index of their parent if(c<0) break; if(c!=0){ if (s[c]>s[c-1]) { c=c-1; } } if (s[p]<=s[c]) break; // break if a parent is smaller than a child tmp=s[p]; s[p]=s[c]; s[c]=tmp; c=p;//declare a parent node as a child node } } void heap_sort(int c,int size,int *s){ int tmp,i,j; //make the first heap for(i=size-1;i>=0;i--){ heap(i,size,s); } //exchange root s and the last s, and sort them for(i=size-1;i>=0;i--){ tmp=s[0]; s[0]=s[i]; s[i]=tmp; for(j=i;j>=0;j--){ heap(j-1,j,s); } } } main() { int num,i,k; int high; int low=0; int s[20]; struct timeval t1,t2; printf("How many elements?:"); scanf("%d",&high); printf("?n"); printf("What number?:"); scanf("%d",&k); printf("?n"); srand((unsigned)time(NULL)); for(i=0;i<high;i++){ s[i]=rand()%10; printf("%d ",s[i]); } printf("?n"); gettimeofday(&t1,0); heap_sort(high-1, high,s); gettimeofday(&t2,0); printf("Time=%dmicrosec?n", t2.tv_usec-t1.tv_usec); printf("The %dth smallest is %d?n ", k,s[k]); }

  • ソートの時間計算について

    ソートの時間計測について以下のようなプログラムを作成したのですが、ソートはうまく動きますが何度試しても処理時間が0.00000秒となってしまいます。どのように改良すればこのような問題を解決できるのでしょうか。ご回答よろしくお願いいたします。 #include <stdio.h> #include <time.h> #define SIZE 100 void swap(int data[], int s, int t){ int tmp = data[s]; data[s] = data[t]; data[t] = tmp; } void Bsort(int data[], int size) { int i, j; for(i=1; i<size; i++){ for(j=(size-1); j>0; j--){ if(data[j] < data[j-1]){ swap(data, j, j-1); } } } } void Ssort(int data[], int size){ int i, j, k, tmp; for(i=1; i<size; i++){ k = data[i-1]; for(j=i; j<size; j++){ if(k>data[j]){ tmp = k; k = data[j]; data[j] = tmp; } } tmp = k; k = data[i-1]; data[i-1] = tmp; } } void printArray(int ar[], int size) { int i; for (i = 0; i < size; i++) printf("%4d", ar[i]); printf("\n"); } int main(void) { int i, x; int data[SIZE]= {412, 54, 595, 329, 24, 488, 313, 272, 129, 210, 670, 516, 342, 541, 491, 640, 167, 117, 726, 206, 474, 762, 153, 292, 1000, 607, 151, 661, 93, 270, 737, 531, 641, 548, 299, 287, 547, 394, 550, 475, 443, 261, 707, 503, 403, 739, 226, 646, 778, 588, 427, 169, 477, 572, 413, 300, 88, 321, 55, 779, 542, 680, 211, 273, 288, 276, 405, 307, 424, 668, 756, 255, 190, 449, 35, 435, 91, 486, 58, 408, 4, 63, 534, 330, 701, 65, 256, 311, 586, 404, 459, 254, 291, 333, 42, 343, 418, 512, 164, 56}; clock_t t1,t2; printf("番号を入力してください。\n1,Bubble Sort\n2,Selection Sort\n"); scanf("%d", &x); switch(x){ case 1: printf("before:"); printArray(data, SIZE); t1 = clock(); Bsort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; case 2: printf("before:"); printArray(data, SIZE); t1 = clock(); Ssort(data, SIZE); t2 = clock(); printf(" after:"); printArray(data, SIZE); printf("処理時間:%f[ms]¥n", (double)(t2 - t1) / CLOCKS_PER_SEC); break; } return 0; }

  • 点数の大きい順に出力する

    #include <iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for(int i=0; i<num; i++){ cin >> test[i]; } } } } for(int j=0; j<num; j++){ cout << j+1 << "番目の人の点数は" << test[j]<< "です。\n"; } return 0; } ---------- の for(int s=0; s<num-1; s++){ for(int t=s+1; t<num; t++){ if(test[t] > test[s]){ int tmp = test[t]; test[t] = test[s]; test[s] = tmp; の部分が理解できません。 s<num-1 は 0<4; ということでしょうか? 値が5つ入力されその値が if(test[t] > test[s]){ にどの様に挿入されるのかが 解りません。