• ベストアンサー

クイックソート

名前と年齢を入力したあとに、1人の名前を入力して2分探索で探索する プログラムを書いたのですが、これにクイックソート法の整列手続き(辞書式順序)を加えたいのですが、どこに何を加えたら動くのか教えていただけないでしょうか。 まだプログラムを習い始めたばかりでプログラム自体も、字下げもろくにできてませんが、どうかよろしくお願いします。 #include<stdio.h> #include<string.h> #include<conio.h> struct record{ char key[20] int dat; }; struct record A[100]; int n=0; void insert(char x[],int y){ n++; strcpy(A[n].key,x); A[n].dat=y; } int binarysearch(char target[],int *pos){ int top,bottom,found,pt; top=n; bottom=1; found=0; while(top>=bottom&&!found){ pt=(top+bottom)/2; if(strcmp(A[pt].key,target)>0) top=pt-1; else if (strcmp(A[pt].key,target)<0) bottom=pt+1; else found=1; } *pos=pt; return found; } int main(void){ char name[100],sname[100]; int old,ptr; scanf("%s",name); while(strcmp(name,"0")){ scanf("%d",&old); insert(name,old); scanf("%s",name); } printf("指定する名前を入力してください\n"); scanf("%s",name); if(binarysearch(sname,&ptr)){ printf("%s %d\n",A[ptr].key,A[ptr].dat); } else printf("いません。\n"); getch(); return0; }

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

  • ベストアンサー
回答No.5

qsort関数を使うのであればこんな感じ?(全角空白文字を半角にしてください) qsort用の比較関数を追加して、Aの添え字をn=0から使うように変更しています。。 #include <stdio.h> #include <string.h> #include <stdlib.h> /* qsort */ struct record{  char key[20];  int dat; }; struct record A[100]; int n=0; void insert(char x[],int y) {  strcpy(A[n].key,x);  A[n].dat=y;  n++; /* n=0から使うので登録後にインクリメント */ } int binarysearch(char target[],int *pos) {  int top,bottom,found,pt;  top=n-1; /* 登録の最大はA[n-1] */  bottom=0; /* 登録の最小はA[0] */  found=0; /* 見つかったら1 */    while (top>=bottom&&!found) {   pt=(top+bottom)/2;   if (strcmp(A[pt].key,target)>0) {    top=pt-1;   } else if (strcmp(A[pt].key,target)<0) {    bottom=pt+1;   } else {    found=1;   }  }  *pos=pt;  return found; } /* qsort用比較関数 */ int reccmp(const void *a, const void *b) {  struct record *aa = (struct record *)a; /* 型をあわせる */  struct record *bb = (struct record *)b; /* 型をあわせる */  return strcmp(aa->key, bb->key); } int main(void){  char name[100],sname[100];  int old,ptr;  int i;  /* データ入力 */  scanf("%s",name);  while(strcmp(name,"0")) {   scanf("%d",&old);   insert(name,old);   scanf("%s",name);  }  /* ソート */  printf("入力データ\n"); for (i=0; i<n; i++) printf("%d %s %d\n",i,A[i].key,A[i].dat);  qsort(A, n, sizeof(struct record), reccmp);  printf("ソート\n"); for (i=0; i<n; i++) printf("%d %s %d\n",i,A[i].key,A[i].dat);  /* 検索入力 */  printf("指定する名前を入力してください\n");  scanf("%s",sname);  /* 検索結果(1個だけ)表示 */  if (binarysearch(sname,&ptr)) {   printf("%s %d\n",A[ptr].key,A[ptr].dat);  } else {   printf("いません。\n");  }  return 0; }

その他の回答 (4)

  • onnobu
  • ベストアンサー率33% (1/3)
回答No.4

「C言語」「アルゴリズム」「クイックソート」などでgoogleで検索してみて下さい。 http://oku.edu.mie-u.ac.jp/~okumura/algo/archive/ などにサンプルのソースコードなどもありました。

noname#75489
noname#75489
回答No.3

C言語のソートアルゴリズムは検索すれば山ほどヒットすると思いますが、ヒントになるような情報は何も見つからなかったのでしょうか? > まだプログラムを習い始めたばかりで 3ヶ月も前にこれくらいのプログラムが書けるなら、クイックソートぐらい楽勝だと思いますが...

参考URL:
http://okwave.jp/qa3981332.html
  • aigaion
  • ベストアンサー率47% (287/608)
回答No.2

>どこに何を加えたら動くのか データの入力が終わった後,事前にソートが必要な処理の前ですよね? クィックソートを加えたいと言っているのに「何を加えたら」という表現が不可解ですね. クィックソート関数を挿入するのではないのですか? >クイックソート法 たぶん,何かの課題だと思います. それだと自力でクィックソートを書かないと駄目ですので 教科書等を調べて自分で書いてみましょう. その上でどうすればよいのかわからないという質問をしてください. この質問は,ここでの禁止事項である「丸投げ」に近い形です.

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>プログラムを書いたのですが、これにクイックソート法の整列手続き(辞書式順序)を加えたいのですが、 >どこに何を加えたら動くのか教えていただけないでしょうか。 このプログラムは自分でコーディングしたのですか? 自分で作成したのなら、何処に何を追加しなければならないか分かると思うのですが。

関連するQ&A

  • クイックソートとチェックプログラム

    こんにちは。以下の問題がわかりません。 特にint Check(){}にはいる部分が。 わかる方、ご回答願います。 /* QuickSortを完成させよう 【自動的に出てきた数を小さい順に並べ、それをチェックする】*/ #include <stdio.h> #include <stdlib.h> int a[1000000]; void MakeData(int *a,int n){ int i; srand(time(&i)); for(i=0;i<n;i++){a[i]=rand();} } int Divide(int *a, int Top, int Botom){ int x,y; while(Top<Botom){ if(a[Top]>a[Top+1]){ x=a[Top]; a[Top]=a[Top+1]; a[Top+1]=x; Top=Top+1; } else{ y=a[Top]; a[Top]=a[Botom]; a[Botom]=y; Botom=Botom-1; } } } int Check(/*ここの関数を作れ*/){/*ここの関数を作れ*/} void QuickSort(int *a, int Top, int Botom){ int K; if(Top>=Botom){return;} K=Divide(a,Top,Botom); QuickSort(a,Top,K-1); QuickSort (a,K+1,Botom); } main(){ int N; printf("データ数?");scanf("%d",&N); MakeData(a,N); if(Check(a,N)==1){printf("並べ変わっている\n");} else{printf("並べ変わっていない\n");} QuickSort(a,0,N-1); if(Check(a,N)==1){printf("並べ変わっている\n");} else{printf("並べ変わっていない\n");} }

  • CTR-Dでプログラムを終了

    学校の課題で、 --- 探索キーとして名前を入力し、入力と一致した場合、その名前と年齢を印字することを繰り返す。 CTR-Dが入力されたとき、プログラムを終了する。 また、文字比較の為に関数strcmpを使用する。 --- という課題が出されたのですが、while(scanf("%s", name) != EOF)を入れるとうまくいきません。 自分で途中までやったものは↓のものです。 どこが違うのか教えてください(>_<) #include<stdio.h> #include<string.h> #define N 10 struct card{ char *name; int age; }; struct card meibo[N] = { "Takahashi", 14, "Kobayashi", 15, "Hosokawa", 17, "Sugimoto", 18, "Sawai", 19, "Itou", 20, "Kawai", 22, "Ishikura", 24, "Oda", 25, "Nakamura", 28 }; int main(void){ char *name; int i; printf("name? : "); scanf("%s", name); while (scanf("%s", name) != EOF){ for (i=0; i<N; i++){ if (strcmp(name, meibo[i].name) == 0) break; } } if (i<N){ printf("%s is %d.\n", meibo[i].name, meibo[i].age);} else{ printf("Not found.\n");} return 0; }

  • クイックソート

    実行時にエラーが出てしまいます。問題点がわかる方お願いします。(インクルード略、800字に収まらなかったので問題があると思われる部分だけ書きます。)ちなみにエラーは外部参照~という感じです。 typedef struct in_data { char bango[No_SIZE]; int ki; }RD; RD *q_sort(RD a[],int n0,int nn); void swap(RD *pa,RD *pb); void main() { FILE *fpa; FILE *fpb; char in_buff[BUFF_SIZE]; RD buff[ARRY_SIZE]; int i; fpa = fopen("data.TXT","r"); for(i=0;i < ARRY_SIZE;i++){ fgets(in_buff,BUFF_SIZE,fpa); strncpy(buff[i].bango,in_buff,No_SIZE); buff[i].bango[No_SIZE] = '\n'; buff[i].ki = atoi(&in_buff[No_SIZE]); } fclose(fpa); q_sort(buff,0,ARRY_SIZE-1); fpb = fopen("result.TXT","w"); for(i=0;i < ARRY_SIZE ; i++) fprintf(fpb,"%*s %*d\n",No_SIZE,buff[i].bango, season_SIZE,buff[i].ki); fclose(fpb); } RD *qsort(RD a[],int n0,int nn) { char x; int i,j; if(nn - n0 == 1){ if(strcmp(a[n0].bango,a[nn].bango)>0) swap(&a[n0],&a[nn]); } else if (nn - n0 >1){ x = (n0+nn)/2;

  • クイックソートでの整列

    10個~20個程度の数列をキーボードから入力し、降順に整理し途中経過と整列後の状態を表示するプログラムを作りなさい。 このような課題が出ているのですが、よくわかりません。授業中に この2つのプログラムを応用すればできるといわれたプログラムがあるのですが、コンパイルするとエラーがたくさん出てきます。 ヒントを教えてください。 1.c #include <stdio.h> #include <stdlib.h> quick_sort(int a[], int l, int r); main(int argc, char *argv) { int i, x[100], n; n = atoi(argv[1]); for(i = 0;i< n;i++); scanf("%d", %x[i]); quick_sort(x, n); printf("sort\n"); for(i = 0;i<n; i++){ printf("%d\n", x[i]); } return ; } 2.c quick_sort(int a[], int l, int r) { int v,i,j,t; if(r>1) { v=a[r]; i=l-1; j=r; while(1) { while(a[++i]<v); while(a[--j]>v) if(j==l)break; if(i>=j)break; t=a[i];a[i]=a[j];a[j]=t; } a[r]=a[i];a[i]=v; quick_sort(a,l,i-1); quick_sort(a,i+1,r); } }

  • ポインタについて

    #include<stdio.h> int main(void) { char str[10]; char *ptr = str; printf("文字列を入力してください。\n"); scanf("%s",ptr); printf("文字列は%sです。",str); return 0; } 上記のプログラムのscanf("%s",ptr);の ptrに&をつけるとなぜ先頭の4文字は入力しても 表示されなくなってしまうのでしょうか? よろしくお願いします。

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • クイックソートのアルゴリズムが分かりません><;

    C言語初心者の学習を終えて、アルゴリズムの構造を学んでいる段階のものです。バブルソートを実装することは成功したのですが、クイックソートが実装できません>< 以下は文字列をバブルソートできるアルゴリズムです。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define MAXCHARSINONELINE 400 #define LINETABLESIZE 100 char linetable[LINETABLESIZE][MAXCHARSINONELINE]; int resultindex[LINETABLESIZE]; int maxtableindex = 0; void addToTable(char *); void initresult(); void mysort(); int mycompare(int, int); void myswap(int, int); char mark[2]; int start; int end; int main(void) { char line[MAXCHARSINONELINE]; char *ret; int i; do { ret = fgets(line,MAXCHARSINONELINE,stdin); if( ret != NULL ) { addToTable(line); } } while(ret != NULL); fprintf(stderr,"sorting...\n"); start = clock(); /* for(i=0; i<10000; i++){ */ initresult(); mysort(); /* } */ end = clock(); fprintf(stderr,"[%f sec]\n",(float)(end-start)/CLOCKS_PER_SEC); fprintf(stderr,"[results]\n"); for( i = 0; i < maxtableindex; i++ ) { printf("(L.%3d):%s",resultindex[i]+1, linetable[ resultindex[i] ]); } return 0; } void addToTable(char *data) { if( maxtableindex >= LINETABLESIZE ) { fprintf(stderr,"Table is full.!\n"); exit(0); } strncpy( linetable[maxtableindex], data, MAXCHARSINONELINE ); maxtableindex++; } void initresult() { int i; for( i = 0; i < maxtableindex; i++ ) { resultindex[i] = i; } } void mysort() { int i,j,k; for( i = maxtableindex-1; i > 0; i-- ) { for( j = 0; j < i; j++ ) { /* printf("--\n"); for(k = 0; k < maxtableindex; k++) { if((k == j) || (k == j + 1)) { strcpy(mark,"*"); } else { strcpy(mark," "); } printf("%s %s", mark, linetable[resultindex[k]]); } printf("--\n"); */ if( mycompare(j, j + 1) > 0) { /* printf("swap %d <----> %d\n",j ,j + 1); */ myswap(j, j + 1); } } } } int mycompare(int i, int j) { return strcmp(linetable[resultindex[i]], linetable[resultindex[j]]); } void myswap(int i, int j) { int tmp; tmp = resultindex[j]; resultindex[j] = resultindex[i]; resultindex[i] = tmp; } このプログラムを改編して、クイックソートにしたいのですが、どこをどうすればよいのでしょうか。 長くなってすみません。 ご回答をお願いします。

  • 検索機能

    名簿管理システムとしてメンバの追加、メンバの削除、メンバリストを名前順(アルファベット昇順)で表示、メンバリストのファイル出力 引数としてファイルパスを指定することによるメンバ初期データの読込ができるプログラムを以下のように作成しました。 #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> typedef struct tagNode{ int no; char name[30]; struct tagNode *next; }Node; Node *ApndNode(Node *top, int no, char *name) { if(top == NULL){ top = (Node*)calloc(1, sizeof(Node)); top->no = no; strcpy(top->name, name); top->next = NULL; }else{ if(strcmp(top->name, name) > 0){ Node *p = (Node*)calloc(1, sizeof(Node)); p->no = no; strcpy(p->name, name); p->next = top; top = p; }else{ top->next = ApndNode(top->next, no, name); } } return top; } Node *DltNode(Node *top, int no, char *name) { if(top != NULL){ if(top->no == no && !strcmp(top->name, name)){ Node *p = top->next; free(top); top = p; }else{ top->next = DltNode(top->next, no, name); } } return top; } void PrintList(Node *top) { if(top != NULL){ printf("%-10d %s\n", top->no, top->name); PrintList(top->next); } } void PrintFile(Node *top) { FILE *fp; char file_name[256]; Node *p = top; printf("file name : "); scanf("%s", file_name); fp = fopen(file_name, "w"); if(!fp) return; while(p != NULL){ fprintf(fp, "%d %s\n", p->no, p->name); p = p->next;} fclose(fp); } void FreeList(Node *top) { while(top != NULL){ Node *p = top->next; free(top); top = p; } } int main(int argc, char *argv[]) { Node *top = NULL; int no, op; char name[30]; while ((op = getopt(argc, argv, "f:")) != -1){ switch (op){ case 'f': do{ FILE *fp = fopen(optarg, "r"); if(!fp) break; while(fscanf(fp, "%d%s", &no, name) == 2) top = ApndNode(top, no, name); fclose(fp); }while(0); } } while(1){ printf("--------command--------\n"); printf("1.Append\n2.Delete\n3.Show\n4.Save\n5.Quit\n"); printf("-----------------------\n"); printf("op : "); scanf("%d", &op); if(op == 5) break; switch(op){ case 1: printf("no : "); scanf("%d", &no); printf("name : "); scanf("%s", name); top = ApndNode(top, no, name); break; case 2: printf("no : "); scanf("%d", &no); printf("name : "); scanf("%s", name); top = DltNode(top, no, name); break; case 3: printf("=========list==========\n"); printf("<no> <name>\n"); PrintList(top); printf("=======================\n"); break; case 4: PrintFile(top); break; } } FreeList(top); return 0; } このプログラムに名前によって検索できる機能をつけるにはどのようにすればよいのでしょうか?教えてください。

  • C言語のソートについて

    C言語で下記のファイルの中身を昇順と降順で出力しようとしているのですが、ソートが上手くいっていない状況です。 どなたか修正点を教えて頂けないでしょうか? 「ファイルの中身」 2022/11/14 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 2022/11/15 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/18 16:20:18 8+8,16.000000 2022/11/17 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 「ソースコード」 #include <stdio.h> #include <string.h> #include <stdlib.h> int cmp_u(const void* a, const void* d) { return *(char*)a - *(char*)d; } int cmp_d(const void* a, const void* d) { return *(char*)d - *(char*)a; } int main() { int r,i,n; FILE* fp; char sin[9][1000]; fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } for (i = 0; i < 9; i++) { fscanf(fp, "%s", &(sin[i])); } fclose(fp); printf("ASC or DESC: "); scanf(" %s", &ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, 9, sizeof(char), cmp_u); } else { qsort(sin, 9, sizeof(char), cmp_d); } for (i = 0; i < 9; i++) { printf("%s\n", sin[i]); } return 0; }

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

    クイックソートのプログラムを作成したのですが、 実行するとセグメンテーション違反が発生して、上手くいきません。何処に原因があるのでしょうか? また、セグメンテーションン違反とはどういったころなのでしょうか? アドバイス宜しくお願いします。 #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; }

専門家に質問してみよう