• ベストアンサー

リスト構造を使ってSortとSearchをするプログラム

タイトルのとおりのプログラムを組んでみました ----------himajin.c----------- #include <stdio.h> #include <string.h> #include <stdlib.h> // 参考:http://www9.plala.or.jp/sgwr-t/c/sec15-5.html // コンパイラ:BCC 5.5 // アイテムの加え方が違う。 struct Item { int data; /* データ */ struct Item *next; /* 次のデータへのポインタ */ }; struct Item *head; struct Item *tail; struct Item *addItem(struct Item *p,int newdata){ struct Item *t; t->data = newdata; t->next = tail; p->next = t; return t; } int main(){ struct Item *item; int inputdata; head = item; item->next = tail; while (scanf("%d", &inputdata) != EOF) { item = addItem(item,inputdata); } /* search(5); sort(); */ return 0; } int sort(){ struct Item *j; struct Item *p; struct Item *t; p = head; t = head; while (p->next != tail){ while (p->data > t->data){ j = t; t = t->next; } j->next = p; p->next = t; p = p->next; } } int search(int searchdata){ struct Item *t; t = head; tail->data = searchdata; while (searchdata != t->data){ t = t->next; } if(t == tail){ printf("Not Found"); } else{ printf("Found"); /*後で考える*/ } return 0; } ---- ...が、コマンドラインで himajin.exe 5 と入力してみたところ、いきなりプログラムが落ちました。何がいけないのでしょうか?

noname#20378
noname#20378

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

  • ベストアンサー
  • ganzou
  • ベストアンサー率29% (25/85)
回答No.1

int main(){ struct Item *item; int inputdata; head = item; のところで、itemには何も入っていません。 なので、 item = (struct Item*)malloc( sizeof(struct Item) ) という一文が必要です。

noname#20378
質問者

補足

皆様の回答、非常に参考になります。失礼ながら、もう少しお付き合いいただけますでしょうか?なお、ソースが長いので、皆様の補足欄を大量に使わせていただきます。 searchの方は(多分)うまく作成できました。 #include <stdio.h> #include <string.h> #include <stdlib.h> // 参考:http://www9.plala.or.jp/sgwr-t/c/sec15-5.html // コンパイラ:BCC 5.5, Cygwin + GCC // アイテムの加え方が違う。 struct Item { int data; /* データ */ struct Item *next; /* 次のデータへのポインタ */ }; struct Item *head; struct Item *tail; struct Item *addItem(struct Item *p,int newdata){ struct Item *t; t = (struct Item*)malloc( sizeof(struct Item) ); t->data = newdata; t->next = tail; p->next = t; return t; } int main(){ struct Item *item; int inputdata; int number; item = (struct Item*)malloc( sizeof(struct Item) ); head = (struct Item*)malloc( sizeof(struct Item) ); tail = (struct Item*)malloc( sizeof(struct Item) ); head = item; item->next = tail; while (scanf("%d", &inputdata) != EOF) { item = addItem(item,inputdata); } search(5); /*5を探す場合*/ show(); return 0; } int search(int searchdata){ struct Item *t; int num; num = 1; t = (struct Item*)malloc( sizeof(struct Item) ); t = head->next; tail->data = searchdata; while (t != tail){ printf("%d\n",t->data); if(t->data == searchdata){ printf("Found. Line %d\n",num); } t = t->next; num = num + 1; } return 0; } int show(){ struct Item *t; t = (struct Item*)malloc( sizeof(struct Item) ); t = head->next; while(t != tail){ printf("%d\n",t->data); t = t->next; } printf("\n"); return 0; }

その他の回答 (2)

回答No.3

>// 参考:http://www9.plala.or.jp/sgwr-t/c/sec15-5.html ここの下の方に関数 add_list の流れの説明がありますが、 himajin2009のプログラムには、2. と3. が抜けてますね。 同じサイトの第10章ポインタを参照して下さい。 わかりやすく説明されていると思います。

参考URL:
http://www9.plala.or.jp/sgwr-t/c/sec10.html
noname#20378
質問者

お礼

すごく汚いソースになりましたが、何とか完成しました!

  • ganzou
  • ベストアンサー率29% (25/85)
回答No.2

struct Item *addItem(struct Item *p,int newdata){ struct Item *t; t->data = newdata; t->next = tail; p->next = t; return t; } のところもNo.1と同じ問題を抱えています。

noname#20378
質問者

補足

Sortが全然うまくいかない。 #include <stdio.h> #include <string.h> #include <stdlib.h> // 参考:http://www9.plala.or.jp/sgwr-t/c/sec15-5.html // コンパイラ:BCC 5.5, Cygwin + GCC // アイテムの加え方が違う。 struct Item { int data; /* データ */ struct Item *next; /* 次のデータへのポインタ */ }; struct Item *head; struct Item *tail; struct Item *addItem(struct Item *p,int newdata){ struct Item *t; t = (struct Item*)malloc( sizeof(struct Item) ); t->data = newdata; t->next = tail; p->next = t; return t; } int main(){ struct Item *item; int inputdata; int number; item = (struct Item*)malloc( sizeof(struct Item) ); head = (struct Item*)malloc( sizeof(struct Item) ); tail = (struct Item*)malloc( sizeof(struct Item) ); head = item; item->next = tail; while (scanf("%d", &inputdata) != EOF) { item = addItem(item,inputdata); } sorts(); show(); return 0; } int sorts(){ struct Item *j; struct Item *p; struct Item *t; struct Item *k; struct Item *z; int c; c = 0; j = (struct Item*)malloc( sizeof(struct Item) ); p = (struct Item*)malloc( sizeof(struct Item) ); t = (struct Item*)malloc( sizeof(struct Item) ); k = (struct Item*)malloc( sizeof(struct Item) ); z = (struct Item*)malloc( sizeof(struct Item) ); r = head; j = head; k = head->next; p = k; t = k->next; while (k->next != tail){ printf("処理中\n"); tail->data = p->data; while ((p->data) > (t->data)){ j = t; t = t->next; c = 1; } printf("%d\n",j->data); k = k->next; if (c == 1){ j->next = p; p->next = t; } p = k; t = p->next; c = 0; show(); } printf("完了\n"); } int show(){ struct Item *t; t = (struct Item*)malloc( sizeof(struct Item) ); t = head->next; while(t != tail){ printf("%d\n",t->data); t = t->next; } printf("\n"); return 0; } これで作成したsort.exeに対し、 1 5 2 3 7 9 6 4 1 2 というテキストファイルを実験的にかましたところ 完了という文字が出る前に出力されたのは 1 5 7 9 でした。

関連するQ&A

  • 双方向リストのバブルソートについて

    双方向リストをバブルソートを用いてソートしたいです。 下記がプログラム(一部)ですが、ソートした後にリスト表示すると 無限ループに陥ります。 どこがいけないのでしょうか。 #include <stdio.h> #include <stdlib.h> struct cell{ int data; struct cell *next, *prev; }; void insert_head(struct cell **head, int num){ struct cell *p, *p1; p = *head; p1 = make_cell(); *head = p1; p1->data = num; p1->next = p; if(p1->next != (struct cell *)NULL){ p1->next = p; p->prev = p1; } } void print_list(struct cell *head){ struct cell *p; p = head; printf("data = \n"); while(p != (struct cell *)NULL){ printf("%d\n", p->data); p = p->next; } } void sort_list(struct cell **head){ struct cell *p, *p2; int i, n; n = 0; p = *head; while(p->next != (struct cell *)NULL){ p = p->next; n++; } for(i = 0, p = *head; i < n-2; i++){ if(p->data > p->next->data){ if(p == *head){ *head = p->next; }else{ p->prev->next = p->next; } p2 = p->next; p->next = p->next->next; p->next->next = p; p->next->next->prev = p; p->next->prev = p->prev; p->prev = p2; }else p = p->next; } } int main(void){ struct cell *head = (struct cell *)NULL; int n; while(1){ printf("1:Insert head 2:Insert tail 3:Delete 4:List 5:Sort 6:Exit\n"); scanf("%d", &n); switch(n){ case 1: printf("num = "); scanf("%d", &n); insert_head(&head, n); break; case 2: printf("num = "); scanf("%d", &n); insert_tail(&head, n); break; case 3: printf("num = "); scanf("%d", &n); delete_cell(&head, n); break; case 4: print_list(head); break; case 5: sort_list(&head); break; case 6: return 0; break; } } }

  • リスト構造のソートで悩んでます。。。

    リスト構造のソートで悩んでます。プログラムの内容はファイルからデータをリスト構造の構造体に読み込み、名前順にソートし結果を表示する。というものです。データの追加や削除はできるのですがソートとなると頭が混乱してしまいお手上げ状態になってしまいました。。。。。 読み込み用のデータとプログラムソースを以下に記載するのでどなたか良きアドバイスをお願いしますm(_ _)m ○データ Sakuragi 16 Rukawa 16 Miyagi 17 Akagi 18 Mitsui 18 ○ソース #include <stdio.h> #include <stdlib.h> #include <string.h> #define MENBER 5 typedef struct data{ char name[BUFSIZ]; int age; struct data *next; }LIST; LIST *newLIST(void); LIST *sort(LIST *); int main(int argc,char *argv[]){ FILE *fp; LIST *p; LIST *np; LIST *npb; LIST *head; char namae[BUFSIZ]; int toshi,i; if((fp=fopen(argv[1],"r"))==NULL){ printf("no file\n"); exit(1); } head = newLIST(); npb =head; for(i=0;i<MENBER;i++){ np = newLIST(); fscanf(fp,"%s %d",namae,&toshi); strcpy(np->name,namae); np->age = toshi; npb->next =np; npb = np; } sort(head); for(p=head->next;p != NULL;p=p->next){ printf("%s\t%d\n",p->name,p->age); } for(p=head->next;p != NULL;p=np){ np = p->next; free(p); } fclose(fp); return(0); } LIST *newLIST(){ LIST *p; p = (LIST *)malloc(sizeof(LIST)); p->next = NULL; return(p); } LIST *sort(LIST *head){ }

  • 連結リストをソート

    学校の課題なんですが正直手も足も出ません。 どういった流れで作成すればいいんでしょうか。 1.連結リストにデータ(文字列)をソートされた順序に追加するようなプログラムを作成する. 2.連結リストのデータを順にプリントするプログラムを作成する。 3.セルをキーとそれに対応する値を含めるように拡張し、与えられたキーを持つセルを探索して  それに対する値を返すプログラムを作成する。 課題を解く際には以下のプログラムを参考にする #include <stdio.h> struct element{ char data; struct element *next; }; struct elements *new() { return((struct element *)malloc(sizeof(struct element))); } struct element *create() { struct element *p; p=new(); p->next=NULL; return(p); } void insert(struct element *l,int k,char item) { struct element *p; if(k>1) insert(l->next,k-1,item); else{ p=new(); p->data=item; p->next=p; l->next=p; } } void delete(struct element *l,int k) { if(k>1) delete(l->next,k-1); else l->next=l->next->next; } char access(struct element *l,int k) { if(k>1) return(access(l->next,k-1)); else return(l->next->data); }

  • リストに整数値があるか判定するプログラム

    ↓のプログラムのint ExistTest(struct BTREE *ptr, int searchdata)を、2分木の生成後に入力した整数値がリストの中にあるかどうかを判定するプログラムにしたいのですが、うまくいきません(>_<) 入力された整数値があれば1、なければ0を返したいのですが。。 どなたかお願いしますm(__)m #include <stdio.h> #include <stdlib.h> struct BTREE {int data; struct BTREE *left; struct BTREE *right;}; void AddLeaf(struct BTREE **ptr, int newdata); void TraverseTree (struct BTREE *ptr); int ExistTest(struct BTREE *ptr, int searchdata); int ExistTest(struct BTREE *ptr, int searchdata){ if (ptr->data == searchdata){ return 1; } else{ ExistTest(ptr->right, searchdata); } } void AddLeaf(struct BTREE **ptr, int newdata){ if (*ptr == NULL){ *ptr = (struct BTREE *)malloc(sizeof(struct BTREE)); (*ptr)->data = newdata; (*ptr)->left = NULL; (*ptr)->right = NULL; } else if (newdata < (*ptr)->data){ AddLeaf(&(*ptr)->left, newdata); } else{ AddLeaf(&(*ptr)->right, newdata); } } void TraverseTree(struct BTREE *ptr){ if (ptr == NULL){ return; } else{ TraverseTree(ptr->left); printf("%3d", ptr->data); TraverseTree(ptr->right); } } int main(void){ struct BTREE *root = NULL; int newdata; int searchdata; while(1){ printf("data > "); scanf("%d", &newdata); if (newdata < 0)break; AddLeaf(&root, newdata); TraverseTree(root); putchar('\n'); } /*ExistTest*/ /* printf("num? : "); scanf("%d", &searchdata); ExistTest(root ,searchdata); */ return 0; }

  • 連結リストによるデータ管理プログラムの解説

    ★から★までのプログラムが、各行ごとにどのような動きをしているのか簡潔な言葉で説明を書いていただきたいのです。必要がないと判断した行はとばして下さって構いません。 (例) printf("hello!"); …hello!と表示 if(a==0){ …aが0なら #include <stdio.h> #include <stdlib.h> struct CELL{ struct CELL *next; char data; }; /* Head CELL CELL CELL +-------+ +-------+ +-------+ +-------+ | ? | *----> | 5 | *----> | 6 | *----> | 8 | / | +-------+ +-------+ +-------+ +-------+ */ main(void){★ struct CELL head; struct CELL *p, *wp; char a; head.next=NULL; printf("?\n"); scanf("%c %*c",&a); while(a!='0'){ printf("mode?\n"); scanf("%c",&mode); if(mode=="a"){ p=&head; while(p->next!=NULL){ p=p->next; } wp=(struct CELL *)malloc(sizeof(struct CELL)); if(wp==NULL){ printf("cannot allocate enough memory.\n"); return 0; } p->next=wp; p->next->data=a; p->next->next=NULL; printf("?\n"); scanf("%c %*c",&a); } if(mode=="p"){ printf("\n\nNow...\n"); p=&head; while(p->next!=NULL){ printf("%c --> \n",p->next->data); p=p->next; } printf("NULL\n"); if(mode=="d"){ p=&head; while(p->next->data==a){ p=p->next; } if(p==NULL) break; wp=p->next->next; while(p->next->data==a) p=wp;★ } } return 0; }

  • c言語の問題です。ファイルからデータを読み込み連結リストに記憶しソートするプログラムです。お願いします

    ソート部分がどうしてもできません。 またソートは以下のアルゴリズムで行うものです 与えられたリストをリストA、ソート済みのリストをリストBとする。処理の開始段階では、リストBは空である。 1.リストAの要素の中で、最大値をもつ要素Cを探す。 2.要素CをリストAから削除する。 3.要素CをリストBの先頭に挿入する。 4.リストAが空であれば終了。空でなければ 1. にもどる。 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct physical Physical; struct physical { char name[41]; int age; float height; float weight; Physical *next; }; void read_data(char *file,Physical *p,Physical *tail); int comp1(const Physical *, const Physical *); int comp2(const Physical *, const Physical *); int comp3(const Physical *, const Physical *); int comp4(const Physical *, const Physical *); void sort(char *arg,Physical *p,Physical *q); Physical *listsort(Physical *p, int (*compar)(const void *, const void *)); int main(void) { char s[20],t,u[20]; Physical *p,*tail,*q; p=malloc(sizeof(Physical)); q=malloc(sizeof(Physical)); tail=malloc(sizeof(Physical)); while(1) { printf("CMD>"); fflush(stdout); fgets(s,20,stdin); sscanf(s,"%c %s",&t,u); switch(t){ case 'q':exit(0); case 'r':read_data(u,p,tail); break; case 's':sort(u,p,q); break; case 'd': while(q!=NULL) { printf("%s %d %.1f %.1f ",q->name,q->age,q->height,q->weight ); q=q->next;} break; } } free(p); return 0; } void read_data(char *file,Physical *p,Physical *tail){ FILE *fp; char string[100]; Physical header; tail=&header; header.next = NULL; p->next = NULL; tail->next = p; tail = p; if ((fp = fopen(file, "r")) == NULL) { exit(1); } while(fgets(string,sizeof(string),fp)!= NULL) { sscanf(string,"%s %d %f %f",p->name,&p->age,&p->height,&p->weight); Physical *tail2; tail2=malloc(sizeof(Physical)); tail2->next=NULL; p->next=tail2; p=tail2; } fclose(fp); } void sort(char *arg,Physical *p,Physical *q){ if(strcmp(arg,"name") == 0) q=listsort(p,(int(*)(const void*, const void*))comp1); if(strcmp(arg,"age") == 0) q=listsort(p,(int(*)(const void*, const void*))comp2); if(strcmp(arg,"height") == 0) q=listsort(p,(int(*)(const void*, const void*))comp3); if(strcmp(arg,"weight") == 0) q=listsort(p,(int(*)(const void*, const void*))comp4); } Physical *listsort(Physical *p,int (*compar)(const void *, const void *)){ Physical *q, *max,*s,*head; s=malloc(sizeof(Physical)); head=malloc(sizeof(Physical)); head=NULL; while(p->next){max = p, q = p->next; while( q->next ) { if( compar(q->next,max->next) ) max = q; q = q->next;} s=max->next; max->next=max->next->next; if(head==NULL) {head=s;} s->next=s; } return head; } int comp1(const Physical *a, const Physical *b){ return (strncmp(a->name,b->name,sizeof(Physical))); } int comp2(const Physical *a, const Physical *b){ if(a->age > b->age) return 1; else return 0; } int comp3(const Physical *a, const Physical *b){ if(a->height > b->height) return 1; else return 0; } int comp4(const Physical *a, const Physical *b){ if(a->weight > b->weight) return 1; else return 0; }

  • C言語 リスト

    (1) /* list.c */ #include <stdio.h> #include <stdlib.h> struct node { int num; struct node *next; }; main() { struct node *head, *p; int x; head = NULL; while(scanf("%d",&x) != EOF) { p = (struct node *)malloc(sizeof(struct node)); p->num = x; p->next = head; head = p; } // リストの要素のnumの値を先頭から順に表示する p=head; while(p!=NULL) { printf("%d\n" ,p->num); p = p->next; } } (2) struct node *q; q = head; while(q->next != NULL) q = q->next; (1)を(2)を使い新しいノードをリストの最後に追加するようにしたいのですが どう書いたら良いのか教えていただきたいです

  • List構造

    Listの尻にノードを追加する関数で困っています。 以下に、ソースの一部を掲載させていただきます。 typedef struct __node{ int data; struct __node *next; }Node; ... /*リストの尻にノードを追加する関数 * 引数: head. リストの先頭ノードのポインタ data. リストの尻に追加したいint型の変数*/ void Insert_Tail(Node *head, int data) { Node *ptr = head; if(ptr == NULL){ /*<ノードが存在しない時には追加されない>*/ /*領域の確保*/      head = (Node*)calloc(1,sizeof(Node)); /*データをセット*/ head->data = data; head->next = NULL; return ; }else{ /*<ノードが存在するときには正常に動作>*/ while(ptr->next != NULL){ ptr = ptr->next; } /*領域の確保*/ ptr->next = (Node*)calloc(1,sizeof(Node));      /*データのセット*/ ptr->next->data = data; ptr->next->next = NULL; } } コメントアウトにも書かせていただきましたが、ノードがすでに存在するときには、正常にノードの最後に追加してくれるのですが、ノードが存在しない時にはリストに追加してくれません。 どうかご指導、ご指摘の程お願いします。

  • C言語のリストのソートについて質問します。

    C言語のリストのソートについて質問します。 こんばんは、aida13です。以前の質問が自己解決しました。回答者のみなさん本当にすみませんでした。 今回はそのアルゴリズムで改善したい点がありましたので投稿させていただきました。以下のソートを実行するとソート自体はうまくいくのですが、見ての通りwhileやifなどを使って何度も実行しなおさないと完全にソートできません(「5 4 3 2 1」→「4 3 2 1 5」(一回ソート))。これを一回でソートできるようにしたいのです。また、降順も同様にそのままsecondとheadを入れ替えたのですが…今度は何度やっても「1 2 3 4 5」→「2 1 3 4 5」(一回ソート)からそれ以上動きません。アドバイスをお願いします。また、出来る限りこの形を保てる形でお願いします。 以下自作ソート #include < stdio.h > #include < stdlib.h > struct ans { int data; struct ans *next; }; struct ans *sort_up(struct ans *head) { int temp; struct ans *second_head; second_head = (struct ans *)malloc(sizeof(struct ans)); second_head = head->next; if( head->next == NULL ) { return head; } else { if( head->data > second_head->data ) { temp = head->data; head->data = second_head->data; second_head->data = temp; sort_up(head->next); } else { sort_up(head->next); } return head; } } struct ans *add_list(int x, struct ans *head) { struct ans *new_head; new_head = (struct ans *)malloc(sizeof(struct ans)); new_head->data = x; new_head->next = head; return new_head; } void show_list(struct ans *head) { if( head == NULL ) { printf("\n\n"); } else { printf("%d ",head->data); show_list(head->next); } } void main() { struct ans *head; head = NULL; head = add_list(1,head); head = add_list(2,head); head = add_list(3,head); head = add_list(4,head); head = add_list(5,head); do { printf("input:"); scanf("%d",&a); if(a==0) { head = sort_up(head); show_list(head); } } while(a==0); }

  • アルゴリズム 線形リスト

    最近リストについて習い始めました。入力したデータと同順に並ぶリストを作成しようと思い、コードを打ったのですが…動作中止の表示がでてしまいました。どこが間違っているのか、ずっと悪戦苦闘して組んでいるのですが、全く出口が見えてきません。何が間違えているのか、はたまた根本的に違うのか、ご指導して頂けると有難いです。 以下、コードです。 #include <stdio.h> #include <stdlib.h> #include <string.h> struct hito{ char name[20]; int age; struct hito *next; }; void main(void){ struct hito *p, *head, *dummy; char new_name[20]; int new_age; dummy = (struct hito *)malloc(sizeof(struct hito)); head = dummy; dummy->next = p; dummy = p; while (scanf("%s %d" , new_name, &new_age) != EOF) { p = (struct hito *)malloc(sizeof(struct hito)); strcpy(p->name, new_name); p->age = new_age; p->next = head; head = p; } while(p != NULL) { printf("\t%-20s %3d\n" , p->name, p->age); p = p->next; } }

専門家に質問してみよう