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

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

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

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

解決済

2回答

4961閲覧

C言語 二分探索木のノードの削除

jun_T

総合スコア2

C

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/09/21 21:52

編集2020/09/26 14:46

C言語で自己参照構造体を用いた二分探索木の削除を行うプログラムが分かりません。

二分探索木から任意のデータのノードを削除する関数deleteがうまく記述できません。

葉のノードの削除はできているのですが、そうでないノードの削除をしようとすると、データ0を持つノードが表れてしまいます。

どのように修正すればよいのでしょうか

現在のソースコード

#include <stdio.h> #include <stdlib.h> struct node { int data; struct node * left ; struct node * right; }; typedef struct node Node ; Node *createNode(int data) { Node *node; if ((node = (Node *) malloc(sizeof(Node))) == NULL) { fprintf(stderr, "Can't allocate memory\n"); exit(1); } node->data = data; node->left = node->right = NULL; return node; } Node *insert(Node *node, int data) { if (node == NULL) { /* 空の木ならば,新しく作ったノードを根とする */ node = createNode(data); } else { if (data < node->data) { /* dataはnodeの左の子に挿入 */ node->left = insert(node->left, data); } else if (data > node->data) { /* dataはrootの右の子に挿入 */ node->right = insert(node->right, data); } else { /* dataは既にあるので何もしない */ data == node->data; } } return node; /* dataを挿入した後の部分木の根を返す */ } Node *delete(Node *node, int data){ Node *child; //削除したいノードとデータを入れ替える子を記憶 if(node == NULL){ return node; } /*削除対象ノードの探索*/ if(node->data > data){ //左の子を探索 node->left = delete(node->left, data); }else if(node->data < data){ //右の子を探索 node->right = delete(node->right, data); }else{ //探索完了 if(node->left == NULL && node->right == NULL){ //葉ノード free(node); return NULL; }else if(node->left == NULL){ //右の子のみ存在 /*データの入替*/ child = node->right; node->data = child->data; node->left = child->left; node->right = child->right; free(child); //子ノードを削除 return node; /* dataを削除した後の部分木の根を返す */ }else if(node->right == NULL){ //左の子のみ存在 /*データの入替*/ child = node->left; node->data = child->data; node->left = child->left; node->right = child->right; free(child); //子ノードを削除 return node; /* dataを削除した後の部分木の根を返す */ }else{ //左右両方の子がいる child = node->left; Node *child_prev = node; while(child->right != NULL){//左の子の最大値を探索 child_prev = child; child = child->right; } node->data = child->data; if(child->left != NULL){ if(child_prev != node){ child_prev->right = child->left; } } free(child); //子ノードを削除 return node; /* dataを削除した後の部分木の根を返す */ } } } void print_tree(Node *node) { static int depth = 0; printf("%*s", depth + 3, " - "); printf("[\"%d\"]\n", node->data); if(node->left != NULL){ depth++; print_tree(node->left); depth--; } if(node->right != NULL){ depth++; print_tree(node->right); depth--; } } int main (void) { int data[11] = {6, 4, 11, 2, 5, 16, 29, 15, 18, 31, 42}; int x; Node *root; for (int i = 0; i < 11; i++) { root = insert(root, data[i]); } print_tree(root); printf("delete ?"); scanf("%d",&x); puts(""); root = delete(root, x); print_tree(root);puts(""); return 0; }

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

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

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

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

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

guest

回答2

0

ベストアンサー

お気楽C言語プログラミング超入門
「C言語 二分探索木のノードの削除」で検索してみました。
とても分かりやすい解説とコードがありますので参考にしてみてください。

投稿2020/09/21 23:30

mjk

総合スコア303

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

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

jun_T

2020/09/22 00:32

理解できました!ありがとうございます!!
guest

0

左枝に繋がるnodeを削除したら、右枝から辿った最左の葉と置き換え
右枝に繋がるnodeを削除したら、左枝から辿った最右の葉と置き換え

でよくないかしら。

投稿2020/09/21 23:20

episteme

総合スコア16612

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問