質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1145閲覧

頭の無い片方向循環リストでリスト内の数字を最大値の値から順に表示させると、先頭に戻った時の先頭の数字の値が0になる。

aoa

総合スコア4

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2022/11/15 05:18

C言語で頭の無い片方向循環リストを作成し、格納した整数の最大値を要素とする節点のうち最も後に現れた節点から順に、再び同じ節点に戻るまで、整数値を標準出力に出力するプログラムを作成していたのですが、最後尾から先頭に戻った時の先頭の数字の値が0になってしまいます。
どのようにすれば解決できるでしょうか?よろしくお願いします。

実現したいこと

最後尾から先頭に戻った時の先頭の数字の値を正常にする。

入出力例

1 3 5 2 4 >(5)(2)(4)(1)(3) 182 -8585 182 -17 182 -9999 >(182)(-9999)(182)(-8585)(182)(-17)

発生している問題

C

1>./a.out 21 33 45 52 64 7(5)(2)(4)(0)(1) 8> ./a.out 9182 10-8585 11182 12-17 13182 14-9999 15(182)(-9999)(0)(182)(-8585)(182)

該当のソースコード

C

1#include<stdio.h> 2#include<stdlib.h> 3 4typedef int elementtype; 5struct node { 6 elementtype element; 7 struct node* next; 8}; 9 10struct node list; 11 12void insert(int i){ 13 struct node* p; 14 struct node* next; 15 struct node* prev; 16 p=(struct node*)malloc(sizeof(struct node)); 17 p->element=i; 18 p->next=&list; 19 prev=&list; 20 for(next=list.next;next!=&list;next=next->next){ 21 prev=next; 22 } 23 prev->next=p; 24} 25 26void print_int_list(int c2) { 27 struct node* p; 28 struct node* q; 29 p=&list; 30 for(c2;c2>0;c2--){ 31 p=p->next; 32 } 33 q=p; 34 for(p;p->next!=q;p=p->next){ 35 printf("(%d)", p->element); 36 } 37 printf("\n"); 38} 39 40 41int main() { 42 int i,c2; 43 int c=0; 44 int n=-9999; 45 char buf[128]; 46 list.next=&list; 47 while (fgets(buf, sizeof(buf), stdin) != NULL) { 48 sscanf(buf,"%d",&i); 49 insert(i); 50 c++; 51 if(i>=n){ 52 n=i; 53 c2=c; 54 } 55 } 56 print_int_list(c2); 57 return 0; 58}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2022/11/15 09:38 編集

関数の頭で変数を全部宣言するのは、早めに止めた方が良いと思います。 for(c2; ~ とか for(p; ~ とかも意味が有りませんので、 for(; ~ に直したほうが良いでしょう。 「頭の無い片方向循環リスト」であれば、グローバル変数の struct node list; がその循環リストに含まれてはいけないと思います。
aoa

2022/11/15 09:52

分かりました。 もう一度考えてみます。
guest

回答2

0

ベストアンサー

オリジナルは入力時にリストを作りながら別途最大値の位置を求めていますが、「片方向循環リストの生成」と「最大値のノードの検索」を分けたほうが良いかもしれません。

片方向循環リストは、先頭もしくは最後を示すポインタのみで生成・管理出来ます。以下のコードでは ( 入力順にリストを生成する必要があるので ) insert を"リストの最後に追加する"関数としています。
最後の入力のノードの次 (next) は最初の入力のノードですので、検索はそのノードから始めるものとし、見つかった最大値のノードから表示を行います。( "n 番目"という指定(パラメータ)では起点となるノードが別に必要ですが、直接ノードを指定すれば必要ありません。)

c

1#include<stdio.h> 2#include<stdlib.h> 3 4typedef int elementtype; 5typedef struct node { 6 elementtype element; 7 struct node* next; 8} NODE; 9 10// node の後ろに追加し, 追加したノードを返す 11struct node *insert(NODE *node, elementtype e) { 12 NODE *new = malloc(sizeof(NODE)); 13 new->element = e; 14 if(node == NULL) { 15 new->next = new; 16 } else { 17 new->next = node->next; 18 node->next = new; 19 } 20 return new; 21} 22 23//最大値のノードを返す 24NODE *searchmax(NODE *start) { 25 if(start == NULL) return NULL; 26 27 NODE *max = start; 28 for(NODE *p = start->next; p != start; p = p->next) { 29 if(max->element <= p->element) max = p; 30 } 31 return max; 32} 33 34// start からの全ノードを表示 35void print(NODE *start) { 36 if(start == NULL) { 37 printf("NULL\n"); 38 return; 39 } 40 41 NODE *p = start; 42 do { 43 printf("(%d)", p->element); 44 } while((p = p->next) != start); 45 printf("\n"); 46} 47 48int main() { 49 NODE *node = NULL; 50 51 char buf[128]; 52 while(fgets(buf, sizeof(buf), stdin) != NULL) { 53 elementtype e; 54 sscanf(buf, "%d", &e); 55 node = insert(node, e); 56 } 57 if(node != NULL) node = node->next; //最初の入力が入っているノード 58 59 print(searchmax(node)); 60 return 0; 61}

投稿2022/11/15 10:10

編集2022/11/15 17:12
jimbe

総合スコア12545

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aoa

2022/11/15 12:50

print関数のところを参考にさせていただきました。 ありがとうございました。
guest

0

0になるというよりは、insertで必ずNodeができるので、listのelementはずっとゼロのままなのが原因。

投稿2022/11/15 05:25

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問