• 締切済み

リスト構造のプログラミング

#include<stdio.h> #include<stdlib.h> typedef struct number{ float x; struct number *next; }Num; void append_list(Num **, float); int main(void) { Num *start,*p; float i,d; start=NULL; for(i=0.0;i<10.0;i++){ append_list(&start,i); } p=start; while(p!=NULL){ printf("%f\n",p->x); p=p->next; } p=start; while(p !=NULL){ Num *q; q=p; p=p->next; free(q); } return 0; } void append_list(Num **s, float n) { Num *end, *new; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*s)->x=n; (*s)->next=NULL; return; }end=(*s); while(end->next !=NULL){ end=end->next; } new=(Num *)malloc(sizeof(Num)*1); new->x=n; new->next=NULL; end->next=new; } 0~9までの数値を順番に追加してリスト構造のデータ構造で 保存するプログラミングを作ったのですが、これにキーボード から入力した1つの実数(0~9)を数値の順序を乱さないよう にその数値を持つ要素を追加するにはどうすればよいのでしょうか?

みんなの回答

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

リスト構造を先頭から順に探索しながら、 リストに登録済みの数値とキーボードから入力した数値との 大小関係を比べて、キーボードから入力した数値を リストのどこに追加すればよいかを決めます。 追加する場所が決まったら、nextポインタを適切に張り替えます。

関連するQ&A

  • 双方向リストのプログラミングのチェック

    指定したファイルを読み込み、一行ずつ構造体に保存し、表示させる。その後、キーボードから指定した行を削除し、処理後の結果を表示させる・・・といったプログラミングを作成しています。 通常の表示の部分はできましたが、後は指定した行の削除の部分ができません。 あらかじめHPで調べてあるので、削除するときは、その削除したい行をまたいで、前後のリストを繋げるといった概念的なのは大体理解できました。 自分なりに考えたり調べて、下のように打ちました。 ですが、キーボードから入力した値をどう関数に対応させていくのか、 delete_head,delete_tailの関数の部分に出る、head,tailは使えない的なエラーの対処の仕方がわからなく、詰まってます。 アドバイス、他にも直す場所等ありましたらお願いします。 #include<stdio.h> #include<stdlib.h> #define LINE 1000 typedef struct num{ char line[LINE]; struct num *next; struct num *prev; }Num; void normal(Num **,Num **,char *); void reverse(Num *,Num *,char *); void delete_head(void); void delete_tail(void); void delete(Num *target); int main(int argc,char *argv[]) { FILE *fp; char line[LINE]; int i=0,j; Num *head,*tail,*p; head=NULL; tail=NULL; fp=fopen("test.txt","r"); if(fp==NULL){ fprintf(stdout,"File not found.\n"); exit(1); } while(fgets(line,LINE,fp)!=NULL) { normal(&head,&tail,line); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); p=tail; while(p!=head){ printf("%s\n",p->line); p=p->prev; } printf("%s\n",p->line); printf("input number\n"); scanf("%d",&j); p=head; for(i=0;i<=j;i++);{ p=p->next; } if(p==head){ delete_head(void); } else if(p==tail){ delete_tail(void); } else{ delete(p->prev); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); fclose(fp); return 0; } void normal(Num **s,Num **e,char *g){ Num *tmp; int i; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*e)=(*s); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ (*s)->line[i]=g[i];} (*s)->next=*e; (*s)->prev=*s; } else{ tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=(*e); (*e)->next=tmp; tmp->next=(*e); (*e)=tmp; } return ; } void reverse(Num *kan1,Num *kan2,char *g){ Num *tmp; int i; tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=kan1; kan1->next=tmp; tmp->next=kan2; kan2->prev=tmp; return ; } void delete_head(void){ Num *second=head->next; if(secound==NULL){ free(head); head=NULL; tail=NULL; } else{ second->prev=NULL; free(head); head=second; } } void delete_tail(void){ Num *second_last=head->prev; if(second_last==NULL){ free(tail); head=NULL; tail=NULL; } else{ second_last->next=NULL; free(tail); tail=second_last; } } void delete(Num *target){ Num *after_target; Num *before_target; after_target=target->next; before_target=target->prev; after_target->prev=target->prev; before_target->next=target->next; free(target); }

  • 構造体について

    typedef struct num{ char rv[1000]; struct number *next; struct number *prev; }Num; このような双方向のリスト構造に void aplist(Num **s,char ns[]){ Num *old, *new; if(*s==NULL){ *s = (Num *)malloc(sizeof(Num)*1); strcpy((*s)->rv,ns); (*s)->next = NULL; (*s)->ago = NULL; return;} old= (*s); while(old->next != NULL){ old = old->next;} new = (Num *)malloc(sizeof(Num)*1); strcpy(new->rv,ns); new->next = NULL; old->next = new; new->prev = old; 関数の中でこのようにnext,oldを指定していったのですが、これでよいでしょうか?また、このリストを逆方向(prevの方向)に表示していきたいのですがどのように書けばよいでしょうか?nsは1行の文字列で、各構造体に1行ずつ入れていっています。

  • 構造体のリスト削除

    かれこれ1時間くらい悩んでいて 問題として 関数delete()を作成し、プログラムを完成させよ(~yabuki/p7.c)。 関数delete()は、与えられたデータをリストから削除するものである。 ただし、データが先頭であっても動作しなければならない。 次のように出力されるはずである。 NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> END PREV hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END NEXT sunyon[23] -> END PREV sunyon[23] -> END list ha nakunarimasita /*******/の間に5行のプログラムを入れる。それ以外にmain()関数を 変更してはならない。 .........;の部分に構造体のメンバーを定義せよ。 というもので、Deleteしていくプログラムをつくりたいのですが NEXT gyuri[23] -> sunyon[23] -> nicole[20] -> hara[20] -> jiyon[17] -> END PREV jiyon[17] -> hara[20] -> nicole[20] -> sunyon[23] -> gyuri[23] -> END セグメントエラー となり、続きができていません。 delete関数のif(p->next != NULL){ のところだけやると 最後まで出るみたいですが、うまくいってません よろしくおねがいします。 ↓ソースです・・・ #include <stdio.h> #include <string.h> struct kara { char name[16]; int age; struct kara *next; struct kara *prev; }; struct kara * delete(struct kara *,struct kara *); struct kara * findend(struct kara *); void* printforw(struct kara *); void* printback(struct kara *); int main() { struct kara a, x, f, m, c, *start, *end, *p; char name[128]; strcpy(a.name, "gyuri"); a.age = 23; strcpy(x.name, "sunyon"); x.age = 23; strcpy(f.name, "nicole"); f.age = 20; strcpy(m.name, "hara"); m.age = 20; strcpy(c.name, "jiyon"); c.age = 17; a.next = &x; x.next = &f; f.next = &m; m.next = &c; c.next = NULL; /********************* 5 lines */ a.prev = NULL; x.prev = &a; f.prev = &x; m.prev = &f; c.prev = &m; /*********************/ start = &a; end = findend(start); printforw(start); printback(end); printf("\n"); p = &c; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); x.next = NULL; p = &a; start = delete(start, p); if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } printf("\n"); p = start; start = delete(start, p); //de senntou wo kaesu if (start == NULL) { printf("list ha nakunarimasita\n"); return 0; } else { end = findend(start); printforw(start); printback(end); } return 0; } struct kara * delete (struct kara *start,struct kara *p) { /*if(p->next->next->next->next) { start = p->next->next->next->next; } */ for(p = start;p != NULL;p = p->next) { start = p->next->next->next; p = start; } /* if(p->next) { start = p->next; } if(p->prev) { start = p->prev; } if(p->next != NULL){ p->next->prev = p->prev; } } */ return p; } struct kara * findend(struct kara *start) { struct kara *pl; for(pl = start;pl != NULL; pl = pl->next){ start = pl; } return start; } void* printforw(struct kara *aa) { struct kara *pl; printf("NEXT "); for ( pl = aa; pl != NULL; pl = pl->next) { printf("%s[%d] -> ", pl->name, pl->age); } printf("END\n"); } void* printback(struct kara *cc) { struct kara *pl; printf("PREV "); //for( ; cc != NULL;cc = cc->prev){ for (pl = cc; pl != NULL; pl = pl->prev) { printf("%s[%d] ->", pl->name,pl->age); } printf("END\n"); }

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

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #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言語 リスト

    (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)を使い新しいノードをリストの最後に追加するようにしたいのですが どう書いたら良いのか教えていただきたいです

  • 構造体へのポインタ

    すみません、構造体へのポインタの配列の扱いに困っています。 下記ソースの struct list *hashtable[HASHSIZE]; の箇所をmain部に入れた場合の 他の関数内での使用の仕方が全くわかりません。 どのように修正すれば良いのでしょうか。 申し訳ありませんが教えてください。 --------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define HASHSIZE 40 #define MAX_KW_LEN 256 #define NUM_KW 23 #define TRUE 1 #define FALSE 0 struct list {  char keyword[MAX_KW_LEN];  struct list *next;   /* 次の list へのポインタ */ }; struct list *hashtable[HASHSIZE]; /* ハッシュテーブル */ /* キーワード ( Cの予約語 ) */ static char kw[NUM_KW][MAX_KW_LEN] = {   "auto", "break", "double",   "enum", "char", "continue", "extern", "float", "for", "int",   "long", "register", "short", "signed", "static",   "struct", "typedef", "union", "unsigned", "return",   "void", "volatile", "while" }; int Hash(char *key); void InitHTable(void); int FindKeyWord(char *key); void ListKeyWord(void); void FreeKeyWord(void); int main(void); int Hash(char *key) {  int hashval = 0;  while (*key != '\0')   hashval += *key++;  return (hashval % HASHSIZE); } void InitHTable(void) {  int i;  struct list *p, *q;  int hashval;  for (i = 0; i < NUM_KW; i++) {   printf("%d\n",i);   if ((FindKeyWord(kw[i])) == FALSE) { /* 登録されていなかったら */             /* メモリを割り付ける */    if ((p = (struct list *)malloc(sizeof(struct list))) == NULL) {     fprintf(stderr, "メモリ不足です。\n");     exit(2);    }    strcpy((*p).keyword, kw[i]);    hashval = Hash(kw[i]);    /* ハッシュ値を求めて */        if (hashtable[hashval] == NULL) { /* 未登録なら */     hashtable[hashval] = p;  /* p の指すアドレスを登録 */     p->next = NULL;    /* リストの末尾に NULL を追加 */    }    else {        /* 既に登録していたら */     q = hashtable[hashval];     while (q->next != NULL) {  /* データがなくなるまで */      q = q->next;    /* リストをたどる */     }     q->next = p;     /* リストの末尾に p の指すアドレスを登録 */     p->next = NULL;    /* その末尾に NULL を追加 */    }   }  } } int FindKeyWord(char *key) {  struct list *p;  for (p = hashtable[Hash(key)]; p != NULL; p = p->next)   if (!strcmp(key, (*p).keyword))  /* 登録済みなら */    return (TRUE);     /* TRUE を返す */   return (FALSE);      /* 未登録ならFALSE を返す */ } void ListKeyWord(void) {  int i;  struct list *p;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; p = p->next) /* p が NULL でなければ */               /* ハッシュ値とキーワードを表示 */    printf("予約語:%s ハッシュ値:%d:\n", (*p).keyword, Hash((*p).keyword)); } /* malloc( ) で割り付けたメモリを解放 */ void FreeKeyWord(void) {  int i;  struct list *p, *q;  for (i = 0; i < HASHSIZE; i++)   for (p = hashtable[i]; p != NULL; ) { /* p が NULL でなければ */    q = p->next;      /* p->next を保存 */    free(p);       /* メモリを解放 */    p = q;        /* p->next を p に代入 */   } } int main(void) {  char word[MAX_KW_LEN];  int i;  InitHTable( );  ListKeyWord( );  for (i = 0; i < 4; i++) {   printf("Cの予約語を入力して下さい ");   fgets(word, 128, stdin);   if ((FindKeyWord(word)) == TRUE)    printf("%s は登録済みです。\n", word);   else    printf("%s は未登録です。\n", word);  }  FreeKeyWord( ); }

  • リスト構造のソートにおいて

    リスト構造のソートにおいて 下記の//■ここの( p->next )->key )が、一番最後のpになった時に p->nextが何も指していないコードだと、MFCだとエラーで落ちてしまうのですが コンソールアプリだと落ちません。(私の勘違いでなければ) そんなことが有るのでしょうか? (下記コードとは関係なしにどんなコードでも良いのですが) while ( p != NULL ) { /* キーが超えたら */ if ( ( key <= p->key && p->next == NULL ) || ( key <= p->key && key > ( p->next )->key ) ) {  //■ここ /* ポインタのつなぎ換え */ wk = p->next; p->next = new_p; new_p->next = wk; /* リストにデータを登録 */ new_p->key = key; strcpy( new_p->name, str ); return head; } p=p->next; }

  • list構造。。。

    リストの末尾にデータを追加すると、最後に追加したデータで今までのリストのデータが上書きされてしまいます。。 以下に、ソースを掲載させていただきます。 void SetNode(List* node_first, List* node_second, int *data) { node_first->move = data; node_first->next = node_second; return ; } /*末尾に挿入*/ void Insert_Tail(List **head, int* data) { List *ptr = *head; if(ptr == NULL){ *head = (List*)calloc(1,sizeof(List)); SetNode(*head, NULL, data); return ; }else{ while(ptr->next != NULL){ ptr = ptr->next; } ptr->next = (List*)calloc(1,sizeof(List)); SetNode(ptr->next, NULL, data); } return ; } void show_list(List *list) { List *ptr = list; while(ptr != NULL){ printf("%d\n",*(ptr->move)); ptr = ptr->next; } return ; } int main(int argc, char** argv) { /*宣言*/ Node* root; /**/ List* top; /* 手順のリスト */ int judge; top = NULL; do{ printf("num:"); scanf("%d",&judge); switch(judge){ case 1: /*データを末尾に追加*/ printf("mem:"); scanf("%d",mem); root->board = mem; Insert_Tail(&top, root->board); break; case 2: /*リストを頭から表示*/ show_list(top); break; default: break; } }while(judge != 0); return 0; } 自分は最後のリストまでたどって、callocしたつもりなのですが、どうもそうではないようで、困っています。 どうか、御指導の程、お願いします。

  • switchとwhile(1)、scanf()を組み合わせてプログラミングしたのですが

    C言語のリストの学習用に、次のようなプログラムを作成しました。 コマンドを入力することでリストを操作するプログラムです。 #include <stdio.h> #include <stdlib.h> typedef struct cell{ int data; struct cell *next; } CELL; CELL head; /* ダミーのセル */ void InsertCell(int x) /* 新しいセルの挿入用関数:iで出る */ { CELL *p, *new; new = (CELL *)malloc(sizeof(CELL)); new->data = x; for(p = &head ; p->next !=NULL ; p = p->next){ if(new->data < (p->next)->data) { new->next = p->next; p->next = new; return; } // xがすでにリストにあるとき、何もせず終了 else if(new->data == (p->next)->data) return; } new->next = NULL; p->next = new; } void Help() /* ヘルプ:hで出る */ { printf("コマンド説明\n"); printf("i : データを挿入\n"); printf("d : データを削除\n"); printf("p : リストを表示\n"); printf("x : プログラム終了\n"); } void PrintList() /* 画面表示用関数:pで出る */ { CELL *p; for(p = &head ; p->next !=NULL ; p = p->next){ printf("%d", (p->next)->data); printf("\n"); } } void DeleteCell(int x) /* 消去用関数:dで出る */ { CELL *p, *tmp; for(p = &head ; p->next !=NULL ; p = p->next){ if((p->next)->data == x) { tmp->next = p->next; p->next = (p->next)->next; free(tmp->next); return; } } printf("そのような数字はありません\n"); } int main(void) { int x; char s; printf("コマンドのヘルプはhを入力してください\n"); while(1){ printf("コマンドを入力してください(i,d,p,x):"); scanf("%c",&s); switch(s) { case 'i': printf("整数を入力してください:"); scanf("%d", &x); InsertCell(x); break; case 'd': printf("整数を入力してください:"); scanf("%d", &x); DeleteCell(x); break; case 'p': PrintList(); break; case 'h': Help(); break; case 'x': printf("終了します"); exit(1); break; default : printf("正しいコマンドを入力してください\n"); break; } } return 0; } これをBorland C++コンパイラでコンパイルしたのち実行すると、 コマンドのヘルプはhを入力してください コマンドを入力してください(i,d,p,x):i 整数を入力してください:10 コマンドを入力してください(i,d,p,x):正しいコマンドを入力してください コマンドを入力してください(i,d,p,x):i 整数を入力してください:100 コマンドを入力してください(i,d,p,x):正しいコマンドを入力してください コマンドを入力してください(i,d,p,x):d 整数を入力してください:10 コマンドを入力してください(i,d,p,x):正しいコマンドを入力してください コマンドを入力してください(i,d,p,x):p 100 コマンドを入力してください(i,d,p,x):正しいコマンドを入力してください コマンドを入力してください(i,d,p,x):x 終了します となり、何故かコマンドも特に入力していないのに 『コマンドを入力してください(i,d,p,x):正しいコマンドを入力してください』 の一文が挟まれます。 これはどういう事でしょうか。解決するにはswitch文をifにするしか手はないのでしょうか? どうかよろしくお願いします。

  • 双方向リスト 指定行の削除について

    現在、双方向リストを使用したプログラミングを作成しています。 コマンドラインから指定したファイルを読み込み、各行の文字列を データとする構造体に記録する。ひとつの構造体に1行の文字列を 記録し、それらの構造体を、行の順番に従ってつながった双方向 リスト構造として、ファイル全体を記録する。 さらに、キーボードから指定した行番号の行を削除する処理を行った後に、再度リストを順方向に表示する・・・といった内容です。 文字列を順、逆順ともに表示できるところまではできたのですが、肝心の行の削除の仕方がわからなくて、困ってます。 具体的には、入力した値をどのように関数に当てはめるのか、つまり行削除の関数の処理をどうすればよいのかがわかりません。 ↓は途中のプログラムです。 fcloseの上にキーボード入力と処理後の表示のコマンド、 一番最後のほうにリスト削除用の関数を入力するのだと思いますが・・・。 OSはLinuxです。 回答宜しくお願いします。 #include<stdio.h> #include<stdlib.h> #define LINE 1000 typedef struct num{ char line[LINE]; struct num *next; struct num *prev; }Num; void normal(Num **,Num **,char *); void reverse(Num *,Num *,char *); int main(int argc,char *argv[]) { FILE *fp; char line[LINE]; int i=0,j; Num *head,*tail,*p; head=NULL; tail=NULL; fp=fopen("test.txt","r"); if(fp==NULL){ fprintf(stdout,"File not found.\n"); exit(1); } while(fgets(line,LINE,fp)!=NULL) { normal(&head,&tail,line); } p=head; while(p!=tail){ printf("%s\n",p->line); p=p->next; } printf("%s\n",p->line); p=tail; while(p!=head){ printf("%s\n",p->line); p=p->prev; } printf("%s\n",p->line); fclose(fp); return 0; } void normal(Num **s,Num **e,char *g){ Num *tmp; int i; if(*s==NULL){ *s=(Num *)malloc(sizeof(Num)*1); (*e)=(*s); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ (*s)->line[i]=g[i];} (*s)->next=*e; (*s)->prev=*s; } else{ tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=(*e); (*e)->next=tmp; tmp->next=(*e); (*e)=tmp; } return ; } void reverse(Num *kan1,Num *kan2,char *g){ Num *tmp; int i; tmp=(Num *)malloc(sizeof(Num)*1); for(i=0;((g[i]!='\0')&&(g[i]!='\n'));i++){ tmp->line[i]=g[i];} tmp->prev=kan1; kan1->next=tmp; tmp->next=kan2; kan2->prev=tmp; return ; }

専門家に質問してみよう