• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:双方向リスト)

双方向リストを使った昇順の数値入力プログラムの作成方法

kmeeの回答

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

初期状態で > np = numtable->right; (= NULL)ですから >np->left = tmp; NUL->left=tmp で不具合発生、となります。 nqが「最後」の場合、np= NULLになりますから if ( nq->right != NULL ) { np->left = tmp; } とするのがよいでしょう。 あと、このやりかただと、最初に確保された構造体がなんの値も不定の値を持ったゴミ要素として最後まで残ります。 > numtable = (struct numbers *)malloc(sizeof(struct numbers)); をnumtable=NULL ; として、 >np = numtable->right; >nq = numtable; >while ( np != NULL) { の前に if (numtable==NULL) { numtable = tmp; continue; } とでも入れるのがいいのではないでしょうか。

tksmsysh
質問者

お礼

ご回答ありがとうございます。 tmp->left = nq; nq->right = tmp; tmp->right = np; np->left = tmp; を tmp->left = nq; nq->right = tmp; tmp->right = np; if ( nq->right != NULL) np->left = tmp; に変更しましたが、結果は変わりませんでした…。

tksmsysh
質問者

補足

すみません、解決しました。 貴重なアドバイス、本当にありがとうございました。

関連する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; } } }

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

    指定したファイルを読み込み、一行ずつ構造体に保存し、表示させる。その後、キーボードから指定した行を削除し、処理後の結果を表示させる・・・といったプログラミングを作成しています。 通常の表示の部分はできましたが、後は指定した行の削除の部分ができません。 あらかじめ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); }

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

    現在、双方向リストを使用したプログラミングを作成しています。 コマンドラインから指定したファイルを読み込み、各行の文字列を データとする構造体に記録する。ひとつの構造体に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 ; }

  • (構造体)双方向連結リストの作成!

    ダミーノードを先頭に、双方向連結リストを作成したいのですがなかなかうまくできません。とりあえず、ダミーノード無しのものはなんとか出来ましたが、循環連結がうまくいっていない次第です。 どうかお力添え願います。 #include<stdio.h> #include<malloc.h> #include<process.h> typedef struct node{ struct node *left; char name[20]; int age; struct node *right; }NODE; NODE *memalloc(void); void main(void) { NODE *head, *tail, *p; tail = NULL; while(p = memalloc(), printf("名前 年齢入力(Ctrl + Zで終了)>"), scanf("%s %d", p -> name, &p -> age) != EOF){ p -> left = tail; tail = p; } p = tail; head = NULL; while(p != NULL){ p -> right = head; head = p; p = p -> left; } head -> left = tail; p = head; printf("リスト表示\n"); while(p != NULL){ printf("名前:%20s 年齢:%5d\n", p -> name, p -> age); p = p -> right; } } NODE *memalloc(void) { NODE *ptr; if((ptr = (NODE *)malloc(sizeof(NODE))) != NULL){ return ptr; } printf("\n動的メモリ割当に失敗しました。\n"); exit(1); return 0; }

  • 単方向リスト

    #include<stdio.h> #include<stdlib.h> #include<string.h> struct Address{ char name[100]; char tel[100]; char email[100]; }; struct AddressList { struct Address addr; //データそのもの struct AddressList *next; //後続ノードへのポインタ struct AddressList *prev; }; struct AddressList *this,*last,*new,*first; struct Address *addr; /*--------ここからmain関数------------*/ int main(void){ int n,i; //何番目に入れるか? char quit[100]; //繰り返しを止める時に利用。 first=last=NULL; //まず初期化 addr =(struct Address *)malloc(sizeof(struct Address)); if(addr==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } while(-1){ printf("整数を入力してください。\n"); scanf("%d",&n); printf("名前を入力してください。\n"); scanf("%s",addr->name); printf("電話番号を入力してください。\n"); scanf("%s",addr->tel); printf("メールアドレスを入力してください。\n"); scanf("%s",addr->email); new =(struct AddressList *)malloc(sizeof(struct AddressList)); //新たに加えるリストの動的メモリー確保 if(new==NULL){ fprintf(stderr,"malloc:error\n"); exit(1); } new->addr=addr; //ここでエラーが発生します。 new->next=NULL; incompatible types in assignment とエラーがでます。 型はあってると思うんですが、、、 よろしくおねがいします。

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

    #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)を数値の順序を乱さないよう にその数値を持つ要素を追加するにはどうすればよいのでしょうか?

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

  • リスト

    リスト構造にしたいのですがどうすればいいでしょうか。 #include <stdio.h> #include <stdlib.h> #include <string.h> struct toy { char name[10]; int number; struct toy next; }; /*プロトタイプ宣言*/ void omocha_toy(struct toy *x); int main( void ) { struct toy *x; if((x =(struct toy *)malloc(sizeof(struct toy))) == NULL) { fprintf(stderr,"エラー\n"); exit(1); } sprintf("x -> name,"Osarusan"); x->score = 12; omocha_toy(x); return 0; } void omocha_toy(struct toy *x) } printf("%s",x->name); printf("%d\n",x->number); } このプログラムで2つ目3つ目をリスト構造を使って作りたいんです。 お願いします。

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

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #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言語初心者です。以下のリスト構造を双方向リストに書き換えたいです。 構造体にstruct transcript *prvs;を追加するのはいいとして、その後どのように変更したらよいでしょうか。関数printingdudeのprvs版を追加し、メイン部でprintingdude_prvs(Z)をすればよいでしょうか。詳しい方、お手数ですがご教示頂きたいです。。 #include <stdio.h> #include <stdlib.h> typedef struct transcript { int no; struct transcript *next; } tra; void printingdude(tra *x) { if (x == NULL) return; printf("%d",x->no); if (x->next != NULL) { printf(", "); printingdude(x->next); } else { printf("\n"); } return; } void free_noud(tra *x) { while (x != NULL) { tra *t = x->next; free(x); x = t; } return; } tra* nnoud(int v, tra* c) { tra *x = (tra *) malloc(sizeof(tra)); if (!x) { printf("\ncan't allocate memory for a new node"); exit(EXIT_FAILURE); } x->no = v; x->next = c; return x; } int main() { tra *Z = NULL; for (int n = 10; n>0; n--) { printingdude(Z); Z = nnoud(n, Z); } printingdude(Z); free_noud(Z); return 0; }