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; }
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/22 00:32