🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

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

Q&A

解決済

2回答

5537閲覧

線形リスト 途中の挿入と削除

ceb

総合スコア11

C

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

0グッド

0クリップ

投稿2019/12/30 06:22

以下の入力による命令が線形リストに反映されるプログラムを作りたいです。

0 :終了
1 :リスト表示
2 num val :リストのnum番目に値valを追加
3 num :リストのnum番目を削除
また、追加と削除に関しては、成功したとき1、失敗したとき0を返すようにする必要があります。

リストの終了(0)、表示(1)、削除(3)はできています。追加が上手くいきません。
追加の命令(2 1 1など)をしたあと、リスト表示を行っても何も表示されませんので、上手く追加ができていないのだと思います。
コードはこちらになります。テンプレートとして用意されたものを使用していますので、私が書いたのはaddNode、deleteNode、showList関数内のみです。今回は追加が上手くいきませんので、addNode関数内のみ見ていただければと思います。
どうぞよろしくお願いいたします。

html

1#include <stdio.h> 2#include <stdlib.h> 3 4#define FAIL_RETURN(flg,message) if(!(flg)){printf("%s",message);freeList();exit(1);} 5 6typedef struct LISTNODE { 7 int data; 8 struct LISTNODE *pNext; 9} ListNode; 10 11ListNode rootNode; 12 13int addNode(int num, int val){ 14 /*write your program.*/ 15 ListNode *pPrevNode = &rootNode; 16 ListNode *pNewNode = (ListNode*)malloc(sizeof(ListNode)); 17 pNewNode -> data = val; 18 pNewNode -> pNext = NULL; 19 20 int Pos=1; 21 pPrevNode = pPrevNode -> pNext; 22 while(pPrevNode != NULL){ 23 pPrevNode = pPrevNode -> pNext; 24 Pos++; 25 } 26 27 pPrevNode = &rootNode; 28 29 if(num <= Pos+1){ 30 31 int pos=1; 32 while(pos<num){ 33 pPrevNode = pPrevNode->pNext; 34 pos++; 35 } 36 37 pNewNode -> pNext = pPrevNode->pNext; 38 pPrevNode-> pNext = pNewNode; 39 40 return 1; 41 }else 42 { 43 return 0; 44 } 45} 46 47int deleteNode(int num){ 48 /*write your program.*/ 49 50 ListNode *nNode = &rootNode; 51 int Pos=1; 52 nNode = nNode -> pNext; 53 while(nNode != NULL){ 54 nNode = nNode -> pNext; 55 Pos++; 56 } 57 58 if(num<=Pos){ 59 60 Pos=1; 61 ListNode *Node = &rootNode; 62 /*削除するノードのひとつ前まで進める*/ 63 while(Pos<num){ 64 Node = Node->pNext; 65 Pos++; 66 } 67 68 69 ListNode *Node2 = &rootNode; 70 Pos = 1; 71 /*削除するノードまで進める*/ 72 while(Pos <= num){ 73 Node2 = Node2->pNext; 74 Pos++; 75 } 76 77 /*前の要素のpNextに削除される要素のpNextをコピー*/ 78 Node->pNext = Node2->pNext; 79 80 free(Node2); 81 return 1; 82 }else 83 { 84 return 0; 85 } 86 87 } 88 89void showList(void) { 90 /*write your program.*/ 91 ListNode *Node; 92 Node = &rootNode; 93 Node = rootNode.pNext; 94 if(Node != NULL){ 95 if(Node->pNext != NULL){ 96 printf("%d", Node->data);} 97 98 Node = Node->pNext; 99 while(Node != NULL){ 100 printf(" %d", Node->data); 101 Node = Node->pNext; 102 } 103 printf("\n"); 104 } 105 106} 107 108void freeList(void) { 109 ListNode *currentNode = rootNode.pNext; 110 ListNode *tmp; 111 112 for (;currentNode != NULL;) { 113 tmp = currentNode; 114 currentNode = currentNode -> pNext; 115 free(tmp); 116 } 117} 118 119 120int main(void) { 121 int op, num, val; 122 char message[256]; 123 124 rootNode.data = 0; 125 rootNode.pNext = NULL; 126 127 128 129 /*addNodeが使えないので確認用 130 ListNode node1, node2, node3; 131 rootNode.pNext = &node1; 132 node1.pNext = &node2; 133 node2.pNext = &node3; 134 node3.pNext = NULL; 135 node1.data = 10; 136 node2.data = 20; 137 node3.data = 30;*/ 138 139 while (scanf("%d", &op), op) { 140 switch (op) { 141 case 1: 142 showList(); 143 break; 144 case 2: 145 scanf("%d%d", &num, &val); 146 sprintf(message, "error in addNode(%d, %d)\n", num, val); 147 FAIL_RETURN(addNode(num, val), message) 148 break; 149 case 3: 150 scanf("%d", &num); 151 sprintf(message, "error in deleteNode(%d)\n", num); 152 FAIL_RETURN(deleteNode(num), message) 153 break; 154 } 155 } 156 157 freeList(); 158 159 return 0; 160}

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

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

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

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

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

guest

回答2

0

確認に使用している showList が正常に動作致しません.
テストされた形跡がコメントにありますが,「データが1件の場合」に表示されるかをテストされていません.

c

1#include <stdio.h> 2#include <stdlib.h> 3 4typedef struct LISTNODE { 5 int data; 6 struct LISTNODE *pNext; 7} ListNode; 8 9ListNode rootNode; 10 11int addNode(int num, int val){ 12 /*write your program.*/ 13 ListNode *node, *pNewNode; 14 for(node=&rootNode; node!=NULL; node=node->pNext) { 15 if(--num == 0) { 16 pNewNode = (ListNode *)malloc(sizeof(ListNode)); 17 pNewNode->data = val; 18 pNewNode->pNext = node->pNext; 19 node->pNext = pNewNode; 20 return 1; 21 } 22 } 23 return 0; 24} 25 26void showList(void) { 27 /*write your program.*/ 28 ListNode *node; 29 printf("showList:"); 30 for(node=rootNode.pNext; node!=NULL; node=node->pNext) { 31 printf(" %d", node->data); 32 } 33 printf("\n"); 34} 35 36void freeList(void) { 37 ListNode *node, *tmp; 38 for(node=rootNode.pNext; node!=NULL; ) { 39 tmp = node; 40 node = node->pNext; 41 free(tmp); 42 } 43} 44 45int main(void) { 46 rootNode.data = 0; 47 rootNode.pNext = NULL; 48 49 showList(); 50 printf("addNode: return=%d\n", addNode(1,10)); 51 showList(); 52 printf("addNode: return=%d\n", addNode(1,20)); 53 showList(); 54 printf("addNode: return=%d\n", addNode(2,30)); 55 showList(); 56 printf("addNode: return=%d\n", addNode(5,40)); 57 showList(); 58 59 freeList(); 60 61 return 0; 62}

text

1showList: 2addNode: return=1 3showList: 10 4addNode: return=1 5showList: 20 10 6addNode: return=1 7showList: 20 30 10 8addNode: return=0 9showList: 20 30 10

投稿2019/12/30 08:28

編集2019/12/30 08:59
jimbe

総合スコア13202

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

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

ceb

2020/01/06 03:59

お返事が遅くなってしまい申し訳ありません。10 20 30の表示ですっかり合っていると思ってしまいました。テストする際にはいくつか条件を変えて行った方がよいと学ぶことができました。ご回答ありがとうございました。
jimbe

2020/01/06 04:18

なお, ご提示のコードでは addNode が 0 を返す場合に malloc した領域が解放されずに残ってしまいます. 挿入が確定してから malloc するか, 0 を返す前に free するようにしてください.
guest

0

ベストアンサー

今回は追加が上手くいきませんので、addNode関数内のみ見ていただければ

showList関数の正しさには自信があるということですか?

C

101:void showList(void) { 202: /*write your program.*/ 303: ListNode *Node; 404: Node = &rootNode; 505: Node = rootNode.pNext; 606: if (Node != NULL) { 707: if (Node->pNext != NULL) { 808: printf("%d", Node->data); 909: } 1010: 1111: Node = Node->pNext; 1212: while (Node != NULL) { 1313: printf(" %d", Node->data); 1414: Node = Node->pNext; 1515: } 1616: printf("\n"); 1717: } 1818:}

rootの次に一つ要素がある状態を想定すると
root[data,pNext] - node1:[data,NULL]
という状態。

これでshowListに入ると、
05:でnode1へのポインタがNodeに入りますね。
06:は真ですが、
07:のifの条件式はnode1のpNextを検査してNULLですからdataの表示は行われません。
11:でNodeはnode1のpNextすなわちNULLになって以降スキップ。

つまり、

追加の命令(2 1 1など)をしたあと、リスト表示を行っても何も表示されません

ということになります。
もう一個要素を追加すると以降は表示されます。07:のifが余計ですね。
まぁ、言い出すと06:のifと12:のwhileの条件が同じあたり、工夫のしようがあるんじゃないか、とかも思います。

ここはあっているはず、と思うと間違いを見逃します。
(addListとかdeleteListがあっているかはちゃんとは見ていませんが)

投稿2019/12/30 08:13

thkana

総合スコア7703

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

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

ceb

2020/01/06 03:56

お返事が遅くなってしまい申し訳ありません。 確認用の10 20 30が表示されたので、すっかり合っていると思い込んでしまっていました。教えていただいたことを確認してみると、たしかに…となりました。とても助かりました。ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問