diff --git a/src/tree.c b/src/tree.c
index 5baa60d16479070c55e7c855eac20367c6aa429d..55e01ca72b78f5702e3e69b86f5593e1a0aa51ab 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -111,6 +111,7 @@ struct tree_t * new_tree(int balanced, int (*preceed)(const void *, const void *
 	tree->preceed = preceed;
 	tree->viewKey = viewKey;
 	tree->viewData = viewData;
+	tree->freeKey = freeKey;
 	tree->freeData = freeData;
 	tree->numelm = 0;
 	tree->root = NULL;
@@ -352,7 +353,7 @@ static struct tree_node_t * insert_into_tree_node(struct tree_node_t * curr, voi
 		// 6 cas
 		int FEX = get_bfactor(curr);
 
-		if(FEX == 2) 
+		if(FEX > 1) 
 		{
 			int FEY = get_bfactor(get_left(curr));
 			if(FEY == 1 || FEY == 0)
@@ -365,7 +366,7 @@ static struct tree_node_t * insert_into_tree_node(struct tree_node_t * curr, voi
 				curr = rotate_right(curr);
 			}
 		}
-		else if(FEX == -2) 
+		else if(FEX < -1) 
 		{
 			int FEY = get_bfactor(get_right(curr));
 			if(FEY == -1 || FEY == 0) 
@@ -419,37 +420,27 @@ struct tree_node_t * tree_find_node(struct tree_node_t * curr, void * key, int (
 }
 
 struct tree_node_t * tree_find_predecessor(struct tree_node_t * curr, void * key, int (*preceed)(const void *, const void *)) {
-	assert(!tree_node_is_empty(curr));
-
-	struct tree_node_t * prev = NULL;
-
-    while (curr) {
-        if (preceed(key, curr->key) > 0) {
-            prev = curr;
-            curr = curr->right;
-        } else {
-            curr = curr->left;
-        }
-    }
+	if (curr == NULL) return NULL;
 
-    return prev;
+	if (preceed(get_tree_node_key(curr), key) >= 0)
+	{
+		if (!tree_node_is_empty(get_left(curr)))
+			return tree_max(curr);
+		return NULL;
+	}
+	else return tree_find_predecessor(get_left(curr), key, preceed);
 }
 
 struct tree_node_t * tree_find_successor(struct tree_node_t * curr, void * key, int (*preceed)(const void *, const void *)) {
-	assert(!tree_node_is_empty(curr));
-	// A FAIRE
-	struct tree_node_t * succ = NULL;
-
-    while (curr) {
-        if (preceed(key, curr->key) < 0) {
-            succ = curr;
-            curr = curr->left;
-        } else {
-            curr = curr->right;
-        }
-    }
+	if (curr == NULL) return NULL;
 
-    return succ;
+	if (preceed(get_tree_node_key(curr), key) <= 0)
+	{
+		if (!tree_node_is_empty(get_right(curr)))
+			return tree_min(curr);
+		return NULL;
+	}
+	else return tree_find_successor(get_right(curr), key, preceed);
 }
 
 /**
@@ -489,9 +480,24 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
 		{
 			curr->right = remove_tree_node(curr->right, key, data, balanced, preceed);
 		} else {
+			struct tree_node_t* orphan = get_left(curr)? get_left(curr) : get_right(curr);
+			if (get_right(curr) && get_left(curr))
+			{
+				// On remplace curr par le plus proche supérieur puis recursion pour l'enlever et on attend les rotations
+				struct tree_node_t* sup = tree_find_successor(curr, key, preceed);
+				set_tree_node_key(curr, get_tree_node_key(sup));
+				set_tree_node_data(curr, get_tree_node_data(sup));
+				set_right(curr, remove_tree_node(get_right(curr), get_tree_node_key(sup), data, balanced, preceed));
+			}
+			else if (orphan) 
+			{
+				// Cas simple, on réattache et on attend le rééquilibrage
+				set_tree_node_key(curr, get_tree_node_key(orphan));
+				set_tree_node_data(curr, get_tree_node_data(orphan));
+				set_left(curr, get_left(orphan));
+				set_right(curr, get_right(orphan));
+			}
 			*data = get_tree_node_data(curr);
-			free(curr);
-			return NULL;
 		}
 	}
 
@@ -502,7 +508,7 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
 		// 6 cas
 		int FEX = get_bfactor(curr);
 
-		if(FEX == 2) 
+		if(FEX > 1) 
 		{
 			int FEY = get_bfactor(get_left(curr));
 			if(FEY == 1 || FEY == 0)
@@ -515,7 +521,7 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
 				curr = rotate_right(curr);
 			}
 		}
-		else if(FEX == -2) 
+		else if(FEX < -1) 
 		{
 			int FEY = get_bfactor(get_right(curr));
 			if(FEY == -1 || FEY == 0) 
@@ -538,7 +544,10 @@ static struct tree_node_t * remove_tree_node(struct tree_node_t * curr, void * k
  */
 void * tree_remove(struct tree_t * T, void * key) {
 	void* data = NULL;
-	remove_tree_node(get_root(T), key, &data, 0, T->preceed);
-	T->freeKey(key);
+	struct tree_node_t* node = remove_tree_node(get_root(T), key, &data, tree_is_balanced(T), T->preceed);
+	if (node)
+	{
+		T->freeKey(key);
+	}
 	return data;
 }