Если я нахожу отца, у которого в детстве только лист, мне нужно убрать этот лист и добавить его значение вместе с отцом
Это мое решение, но у меня проблема при попытке удалить лист
bool isLeaf(tree a){ //function to verify if the node is a leaf
if(a->left==NULL && a->right==NULL)
return true;
else
return false;
}
void removeLeaves(tree* a){
if(*a == NULL) return;
//verify if the node has only a child
if(((*a)->left==NULL&&(*a)->right!=NULL) || ((*a)->right==NULL&&(*a)->left!=NULL)){
if((*a)->right==NULL){ //if has only left child,verify if it is a leaf
if(isLeaf((*a)->left)){
(*a)->info = (*a)->info + (*a)->left->info;
free((*a)->left);
}
}
if((*a)->left==NULL){ //if has only right child,verify if it is a leaf
if(isLeaf((*a)->right)){
(*a)->info = (*a)->info + (*a)->right->info;
free((*a)->right);
}
}
}
removeLeaves(&((*a)->left));
removeLeaves(&((*a)->right));
}
Минимальные:
if((*a)->right==NULL){ //if has only left child,verify if it is a leaf
if(isLeaf((*a)->left)){
(*a)->info = (*a)->info + (*a)->left->info;
free((*a)->left);
Если я достигну этой точки (слева есть только ребенок, и это лист), я суммирую его значение с отцом, а затем освобождаю его. без свободного я получаю сумму, но со свободным я получаю ошибку сегментации. То же самое только с ребенком справа.
Edit1:
Я изменил условие на:
if(((*a)->right==NULL&&(*a)->left!=NULL) && isLeaf((*a)->left)){
(*a)->info = (*a)->info + (*a)->left->info;
free((*a)->left);
(*a)->left = NULL;
}
И это работает, но я не понимаю, почему.
Edit2: (реализация со структурой)
#include <stdio.h>
#include <cstdlib>
typedef int InfoTree;
typedef struct StructTree {
InfoTree info;
struct StructTree* right;
struct StructTree* left;
} NodeTree;
typedef NodeTree* Tree;
//functions
Tree createTree(InfoTree infoRoot,Tree left,Tree right);
Tree emptyTree();
void print_tree(Tree a);
bool isLeaf(Tree a);
void removeLeaves(Tree* a);
int main(){
/* Binary Tree: */
/* 3 */
/* / \ */
/* 7 5 */
/* / \ \ */
/* 4 2 9 */
/* / */
/* 6 */
Tree A = createTree( 6 , emptyTree(), emptyTree() ) ;
Tree B = createTree( 2 , emptyTree(), emptyTree() ) ;
Tree C = createTree( 9 , emptyTree(), emptyTree() ) ;
Tree D = createTree( 5 , emptyTree(), C);
Tree E = createTree( 4 , A, emptyTree());
Tree F = createTree( 7 , E, B);
Tree H = createTree( 3 , F, D);
Tree t = H;
print_tree(t);
removeLeaves(&t);
printf("\n");
print_tree(t);
return 0;
}
Tree createTree(InfoTree infoRoot,
Tree left,
Tree right) {
Tree a = (Tree) malloc(sizeof(Tree));
a->info = infoRoot;
a->left = left;
a->right = right;
return a;
}
Tree emptyTree() {
return NULL;
}
void print_tree(Tree a) {
if (a==NULL) {
printf("()");
}
else {
printf("( %d ",a->info);
print_tree(a->left);
printf(" ");
print_tree(a->right);
printf(" )");
}
}
bool isLeaf(Tree a){ //function to verify if the node is a leaf
if(a->left==NULL && a->right==NULL)
return true;
else
return false;
}
void removeLeaves(Tree* a){
if(*a == NULL) return;
//verify if the node has only a child
if(((*a)->left==NULL&&(*a)->right!=NULL) || ((*a)->right==NULL&&(*a)->left!=NULL)){
if((*a)->right==NULL){ //if has only left child,verify if it is a leaf
if(isLeaf((*a)->left)){
(*a)->info = (*a)->info + (*a)->left->info;
free((*a)->left);
(*a)->left = NULL;
}
}
if((*a)->left==NULL){ //if has only right child,verify if it is a leaf
if(isLeaf((*a)->right)){
(*a)->info = (*a)->info + (*a)->right->info;
free((*a)->right);
(*a)->right = NULL;
}
}
}
removeLeaves(&((*a)->left));
removeLeaves(&((*a)->right));
}
Это оригинальный исходный код с древовидной структурой и функциями для работы с деревом. Если я изменяю это с вышеупомянутыми условиями (сначала Edit1), это работает, но я не понимаю почему.
Спасибо