From f99d2ae63f824dae55dfacbe16b09573c0519b89 Mon Sep 17 00:00:00 2001
From: vitawrap <thevitawrap@gmail.com>
Date: Fri, 7 Apr 2023 16:33:04 +0200
Subject: [PATCH] =?UTF-8?q?Trees:=20=C3=A9quilibr=C3=A9s=20fonctionnels?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/test.c |  29 +++++++----
 src/tree.c | 143 +++++++++++++++++------------------------------------
 2 files changed, 65 insertions(+), 107 deletions(-)

diff --git a/src/test.c b/src/test.c
index 01f78ec..82d411b 100644
--- a/src/test.c
+++ b/src/test.c
@@ -103,7 +103,7 @@ void test_multiple_list_insert_after()
 
 void viewStr(void* str)
 {
-	printf("%s", str);
+	printf("%s", (const char*)str);
 }
 
 int preceed(void* a, void* b)
@@ -120,28 +120,37 @@ void test_trees_balanced()
 	const char* b_str = "val de B!!";
 	int* c = malloc(sizeof(int));	*c = 94;
 	const char* c_str = "val de C!!!";
+	int* d = malloc(sizeof(int));	*d = 3;
+	const char* d_str = "val de D!!!";
 	
-	printf("Arbre 1: ");
+	printf("Arbre 1            : ");
 	struct tree_t * tree = new_tree(0, preceed, viewInt, viewStr, freeInt, NULL);
-	tree_insert(tree, a, a_str);
-	tree_insert(tree, c, c_str);
+	tree_insert(tree, d, d_str);
 	tree_insert(tree, b, b_str);
+	tree_insert(tree, c, c_str);
+	tree_insert(tree, a, a_str);
 	view_tree(tree);
+	delete_tree(tree, 0, 0);
 
-	printf("Arbre 2: ");
-	tree = new_tree(0, preceed, viewInt, viewStr, freeInt, NULL);
+	printf("Arbre 1 (equilibré): ");
+	tree = new_tree(1, preceed, viewInt, viewStr, freeInt, NULL);
+	tree_insert(tree, d, d_str);
 	tree_insert(tree, b, b_str);
 	tree_insert(tree, c, c_str);
 	tree_insert(tree, a, a_str);
 	view_tree(tree);
+	delete_tree(tree, 0, 0);
 
-	printf("Arbre 3: ");
-	tree = new_tree(0, preceed, viewInt, viewStr, freeInt, NULL);
-	tree_insert(tree, b, b_str);
+	printf("Arbre 2 (equilibré): \n");
+	tree = new_tree(1, preceed, viewInt, viewStr, freeInt, NULL);
 	tree_insert(tree, a, a_str);
+	view_tree(tree);
+	tree_insert(tree, b, b_str);
+	view_tree(tree);
 	tree_insert(tree, c, c_str);
 	view_tree(tree);
-
+	tree_insert(tree, d, d_str);
+	view_tree(tree);
 	delete_tree(tree, 1, 0);
 }
 
diff --git a/src/tree.c b/src/tree.c
index 3543e62..5baa60d 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -228,6 +228,18 @@ void view_tree(const struct tree_t * T) {
 	puts("]");
 }
 
+/**
+ * @brief
+ * Fonction utilitaire pour obtenir la taille d'un sous-arbre raçiné à \p node.
+*/
+static int get_height(struct tree_node_t* node) {
+	if (node == NULL)
+		return 0;
+	int lh = get_height(get_left(node));
+	int rh = get_height(get_right(node));
+	return max(lh, rh) + 1;
+}
+
 /**
  * @brief
  * Effectuer une rotation gauche autour du nœud \p y.
@@ -246,47 +258,16 @@ void view_tree(const struct tree_t * T) {
 static struct tree_node_t * rotate_left(struct tree_node_t * y) {
 	assert(y);
 	assert(get_right(y));
-	// A FAIRE
 
 	//ROTATION A GAUCHE
 	struct tree_node_t *x = get_right(y);
-	struct tree_node_t *T2 = get_left(x);
+	struct tree_node_t *z = get_left(x);
 
 	set_left(x, y);
-	set_right(y, T2);
-
-	// MAJ DES BFACTOR
-	int bfactor_x = get_bfactor(x);
-	int bfactor_y = get_bfactor(y);
-
-	if (bfactor_y == -2 && bfactor_x == -1) {
-		set_bfactor(x, 0);
-		set_bfactor(y, 1);
-	} else if (bfactor_y == -2 && bfactor_x == 0) {
-		set_bfactor(x, 0);
-		set_bfactor(y, 0);
-	} else if (bfactor_y == -1 && bfactor_x == 1) {
-		int bfactor_T2 = get_bfactor(T2);
-		if (bfactor_T2 == -1) {
-			set_bfactor(x, 0);
-			set_bfactor(y, 1);
-		} else if (bfactor_T2 == 0) {
-			set_bfactor(x, 0);
-			set_bfactor(y, 0);
-		} else if (bfactor_T2 == 1) {
-			set_bfactor(x, -1);
-			set_bfactor(y, 0);
-		}
-	} else if (bfactor_y == -1 && bfactor_x == -1) {
-		set_bfactor(x, 0);
-		set_bfactor(y, 0);
-	} else if (bfactor_y == -1 && bfactor_x == 0) {
-		set_bfactor(x, -1);
-		set_bfactor(y, 1);
-	} else if (bfactor_y == -2 && bfactor_x == -2) {
-		set_bfactor(x, 0);
-		set_bfactor(y, 0);
-	}
+	set_right(y, z);
+
+	set_bfactor(y, max(get_height(get_left(y)), get_height(get_right(y))) + 1);
+	set_bfactor(x, max(get_height(get_left(x)), get_height(get_right(x))) + 1);
 
 	return x;
 }
@@ -309,42 +290,16 @@ static struct tree_node_t * rotate_left(struct tree_node_t * y) {
 static struct tree_node_t * rotate_right(struct tree_node_t * x) {
 	assert(x);
 	assert(get_left(x));
-	// A FAIRE
 
 	//ROTATION A DROITE
 	struct tree_node_t *y = get_left(x);
-	struct tree_node_t *T2 = get_right(y);
+	struct tree_node_t *z = get_right(y);
 
 	set_right(y, x);
-	set_left(x, T2);
-
-	// MAJ DES BFACTORS
-	int bfactor_y = get_bfactor(y);
-	int bfactor_x = get_bfactor(x);
-
-	if (bfactor_x == 1 && bfactor_y == 1) {
-		set_bfactor(x, 0);
-		set_bfactor(y, -1);
-	// if ((bfactor_x == 2 && bfactor_y == 1) ||
-	// 	(bfactor_x == 1 && bfactor_y == 0) ||
-	// 	(bfactor_x == 2 && bfactor_y == 2) ||
-	// 	(bfactor_x == 2 && bfactor_y == 0))
-	} else if (bfactor_x > 0 && bfactor_y >= 0) {
-		set_bfactor(x, 0);
-		set_bfactor(y, 0);
-	} else if (bfactor_x == 1 && bfactor_y == -1) {
-		int bfactor_T2 = get_bfactor(T2);
-		if (bfactor_T2 == -1) {
-			set_bfactor(x, 1);
-			set_bfactor(y, 0);
-		} else if (bfactor_T2 == 0) {
-			set_bfactor(x, 0);
-			set_bfactor(y, 0);
-		} else if (bfactor_T2 == 1) {
-			set_bfactor(x, 0);
-			set_bfactor(y, 1);
-		}
-	}
+	set_left(x, z);
+
+	set_bfactor(x, max(get_height(get_left(x)), get_height(get_right(x))) + 1);
+	set_bfactor(y, max(get_height(get_left(y)), get_height(get_right(y))) + 1);
 
 	return y;
 }
@@ -385,10 +340,8 @@ static struct tree_node_t * insert_into_tree_node(struct tree_node_t * curr, voi
 	else { // recherche récursif de la position à insérer + mise à jour du facteur d'équilibre
 		int cmp = preceed(key, get_tree_node_key(curr));
 		if (cmp < 0) {       //Cas 1 : clé du nv noeud inf a noeud curr => nv noeud dans curr->left
-			increase_bfactor(curr);
 			curr->left = insert_into_tree_node(curr->left, key, data, balanced, preceed);
 		} else if (cmp > 0) { //Cas 2 : clé du nv noeud sup a noeud curr => nv noeud dans curr->right
-			decrease_bfactor(curr);
 			curr->right = insert_into_tree_node(curr->right, key, data, balanced, preceed);
 		} 
 	}//FIN PARTIE 1
@@ -398,33 +351,33 @@ static struct tree_node_t * insert_into_tree_node(struct tree_node_t * curr, voi
 		// Gérer ici les rotations
 		// 6 cas
 		int FEX = get_bfactor(curr);
-		int FEY = get_bfactor(FEX > 0? curr->left : curr->right); 
 
 		if(FEX == 2) 
 		{
+			int FEY = get_bfactor(get_left(curr));
 			if(FEY == 1 || FEY == 0)
 			{
-				rotate_right(curr);
+				curr = rotate_right(curr);
 			}
 			else if(FEY == -1)
 			{
-				rotate_left(FEX > 0? curr->left : curr->right);
-				rotate_right(curr);
+				curr->left = rotate_left(get_left(curr));
+				curr = rotate_right(curr);
 			}
 		}
-		else if(FEY == -2) 
+		else if(FEX == -2) 
 		{
-			if(FEX == -1 || FEX == 0) 
+			int FEY = get_bfactor(get_right(curr));
+			if(FEY == -1 || FEY == 0) 
 			{
-				rotate_left(FEX > 0? curr->left : curr->right);
+				curr = rotate_left(curr);
 			}
-			else if(FEX == 1)
+			else if(FEY == 1)
 			{
-				rotate_right(curr);
-				rotate_left(FEX > 0? curr->left : curr->right);
+				curr->right = rotate_right(get_right(curr));
+				curr = rotate_left(curr);
 			}
 		}
-
 	}
 
 	return curr;
@@ -435,7 +388,7 @@ static struct tree_node_t * insert_into_tree_node(struct tree_node_t * curr, voi
  */
 void tree_insert(struct tree_t * T, void * key, void * data) {
 	struct tree_node_t* root = get_root(T);
-	struct tree_node_t* node = insert_into_tree_node(get_root(T), key, data, 0, T->preceed);
+	struct tree_node_t* node = insert_into_tree_node(get_root(T), key, data, tree_is_balanced(T), T->preceed);
 	if (!root)
 		set_root(T, node);
 	increase_tree_size(T);
@@ -531,11 +484,9 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
 		int cmp = preceed(key, get_tree_node_key(curr));
 		if (cmp < 0)
 		{
-			decrease_bfactor(curr);
 			curr->left = remove_tree_node(curr->left, key, data, balanced, preceed);
 		} else if (cmp > 0)
 		{
-			increase_bfactor(curr);
 			curr->right = remove_tree_node(curr->right, key, data, balanced, preceed);
 		} else {
 			*data = get_tree_node_data(curr);
@@ -548,37 +499,35 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
 	if (balanced && curr) {
 		// PARTIE 2 :
 		// Gérer ici les rotations
-		//6 cas
-
+		// 6 cas
 		int FEX = get_bfactor(curr);
-		int FEY = get_bfactor(FEX > 0? curr->left : curr->right);
 
 		if(FEX == 2) 
 		{
+			int FEY = get_bfactor(get_left(curr));
 			if(FEY == 1 || FEY == 0)
 			{
-				rotate_right(curr);
+				curr = rotate_right(curr);
 			}
 			else if(FEY == -1)
 			{
-				rotate_left(FEX > 0? curr->left : curr->right);
-				rotate_right(curr);
+				curr->left = rotate_left(get_left(curr));
+				curr = rotate_right(curr);
 			}
 		}
-		else if(FEY == -2) 
+		else if(FEX == -2) 
 		{
-			if(FEX == -1 || FEX == 0) 
+			int FEY = get_bfactor(get_right(curr));
+			if(FEY == -1 || FEY == 0) 
 			{
-				rotate_left(FEX > 0? curr->left : curr->right);
+				curr = rotate_left(curr);
 			}
-			else if(FEX == 1)
+			else if(FEY == 1)
 			{
-				rotate_right(curr);
-				rotate_left(FEX > 0? curr->left : curr->right);
+				curr->right = rotate_right(get_right(curr));
+				curr = rotate_left(curr);
 			}
 		}
-
-		// A FAIRE
 	}
 
 	return curr;
-- 
GitLab