#include "Tree_Bin.h"
#include <stdlib.h>
TBNode::TBNode (void *new_element) { /*Creation d'un noeud dans l'arbre*/
this->element = new_element;
this->left_son = NULL;
this->right_son = NULL;
this->father = NULL;
}
/*Insertion d'un noeud dans l'arbre, la derniere option est facultative, utilisée pour la fonction de comparaison*/
/*La méthode renvoie la nouvelle racine de l'arbre*/
void TBNode::insert_node (p_TBNode new_node, int (*compare_element_TB) (void *, void *, void *), void *option) {
p_TBNode current_node = this; /*Noeud courant*/
p_TBNode father_node = NULL; /*Père du noeud courant*/
while (current_node != NULL) { /*Tant que je ne suis pas sur un emplacement non vide, je descend dans l'arbre*/
father_node = current_node;
if ((*compare_element_TB) (new_node->element, current_node->element, option) < 1) { /*Je regarde si mon noeud doit etre inserer a gauche ou a droite*/
current_node = current_node->left_son;
}
else {
current_node = current_node->right_son;
}
}
new_node->father = father_node;
if ((*compare_element_TB) (new_node->element, father_node->element, option) < 1) { /*Je regarde si mon noeud doit etre inserer a gauche ou a droite*/
father_node->left_son = new_node;
}
else {
father_node->right_son = new_node;
}
}
/*Recherche d'un élément dans l'arbre*/
p_TBNode TBNode::find_node (void *required_element, int (*compare_element_TB) (void *, void *, void *), void *option) {
if (!compare_element_TB (required_element, this->element, option)) {
return this;
}
if ((*compare_element_TB) (required_element, this->element, option) < 1) { /*Je regarde si l'élément recherché est à gauche ou à droite du noeud courant*/
return this->left_son->find_node (required_element, compare_element_TB, option); /*Recursivité sur le fils gauche*/
}
else {
return this->right_son->find_node (required_element, compare_element_TB, option); /*Recursivité sur le fils droit*/
}
}
/*Renvoie le premier noeud qui devrait suivre le noeud en argument*/
p_TBNode TBNode::find_successor (void) {
p_TBNode temp_node_1, temp_node_2;
if (this->right_son != NULL) {
temp_node_1 = this->right_son;
while (temp_node_1->left_son != NULL) {
temp_node_1 = temp_node_1->left_son;
}
return temp_node_1;
}
temp_node_1 = this->father;
temp_node_2 = this;
while (temp_node_1 != NULL) {
if (temp_node_2 == temp_node_1->right_son) {
temp_node_2 = temp_node_1;
temp_node_1 = temp_node_1->father;
continue;
}
break;
}
return temp_node_1;
}
/*Renvoie le premier noeud qui devrait précéder le noeud en argument*/
p_TBNode TBNode::find_predeccessor (void) {
p_TBNode temp_node_1, temp_node_2;
if (this->left_son != NULL) {
temp_node_1 = this->left_son;
while (temp_node_1->right_son != NULL) {
temp_node_1 = temp_node_1->right_son;
}
return temp_node_1;
}
temp_node_1 = this->father;
temp_node_2 = this;
while (temp_node_1 != NULL) {
if (temp_node_2 == temp_node_1->left_son) {
temp_node_2 = temp_node_1;
temp_node_1 = temp_node_1->father;
continue;
}
break;
}
return temp_node_1;
}
p_TBNode TBNode::delete_node (p_TBNode node_to_delete) {
p_TBNode temp_node_1, temp_node_2;
void *temp_element;
if (node_to_delete->left_son == NULL || node_to_delete->right_son == NULL) { /*Si un des deux fils du noeud à effacer est NULL*/
temp_node_1 = node_to_delete; /*La premiere variable pointe sur le noeud a effacer*/
}
else {
temp_node_1 = node_to_delete->find_successor (); /*sinon elle pointe sur le premier element qui sui le noeud a effacer*/
}
if (temp_node_1->left_son != NULL) { /*Si jamais le fils gauche de la premiere variable n'est pas NULL*/
temp_node_2 = temp_node_1->left_son; /*La deuxieme prend la valeur du fils gauche de la premiere*/
}
else {
temp_node_2 = temp_node_1->right_son; /*Sinon elle prend la valeur de son fils droit*/
}
if (temp_node_2 != NULL) { /*Si le premier a bien un fils*/
temp_node_2->father = temp_node_1->father; /*le pere de la deuxieme est le pere de la premiere variable*/
}
if (temp_node_1->father == NULL) { /*Si la premiere variable etait la racine*/
*this = temp_node_2; /*la deuxieme devient la racine*/
}
else { /*Sinon je verifie si la premiere est le fils gauche de la seconde*/
if (temp_node_1 == temp_node_1->father->left_son) { /*si c'est le cas alors le fils gauche de la premiere devient la seconde*/
temp_node_1->father->left_son = temp_node_2;
}
else {
temp_node_1->father->right_son = temp_node_2; /*sinon la deuxieme devient le fils droit de la premiere*/
}
}
if (temp_node_1 != node_to_delete) { /*si la premiere nest pas le noeud a effacer, je donne a l'element a effacer l'element de la premiere variable*/
temp_element = node_to_delete->element;
node_to_delete->element = temp_node_1->element;
temp_node_1->element = temp_element;
}
return temp_node_1;
}