title: Note
Dans cette section, nous allons aborder la suppression d’un élément spécifique dans une liste simplement chaînée. Nous commencerons par la fonction brute `delete_node`, suivie d’une version contextuelle avec une gestion robuste des erreurs et des cas limites. Le tout sera conforme aux standards 42 School, et structuré pour faciliter l’apprentissage.
🧩 5. Supprimer un Élément Spécifique (delete_node)
Version Brute de la Fonction
Voici la fonction brute pour supprimer un nœud spécifique contenant une valeur donnée. Elle parcourt la liste pour trouver le nœud cible, le supprime, et met à jour les liens.
void delete_node(t_node **head, int value)
{
t_node *current;
t_node *prev;
if (!head || !*head)
return;
// Si le nœud à supprimer est le head
if ((*head)->data == value)
{
current = *head;
*head = (*head)->next;
free(current);
return;
}
prev = *head;
current = (*head)->next;
while (current)
{
if (current->data == value)
{
prev->next = current->next;
free(current);
return;
}
prev = current;
current = current->next;
}
}
Explication de la Fonction
-
Validation des Pointeurs:
- Vérifie si
head
ou*head
est NULL pour éviter les erreurs. - Si la liste est vide, la fonction ne fait rien.
- Vérifie si
-
Suppression du Head:
- Vérifie si la valeur à supprimer se trouve au niveau du
head
. - Met à jour
*head
pour pointer sur le nœud suivant, et libère le head.
- Vérifie si la valeur à supprimer se trouve au niveau du
-
Suppression d’un Nœud au Milieu ou à la Fin:
- Parcourt la liste avec deux pointeurs :
prev
(le nœud précédent) etcurrent
(le nœud actuel). - Si
current->data
correspond à la valeur, met à jourprev->next
pour sauter le nœud courant, puis le libère.
- Parcourt la liste avec deux pointeurs :
-
Cas où la Valeur n’Existe Pas:
- Si la valeur n’est pas trouvée dans la liste, la fonction parcourt la liste jusqu’au bout sans rien faire.
Intégration dans un Contexte Plus Large
Voici un programme complet pour illustrer l’utilisation de delete_node
.
Fonctions Auxiliaires
Structure et Création de Nœud
typedef struct s_node {
int data;
struct s_node *next;
} t_node;
t_node *new_node(int data)
{
t_node *temp;
temp = malloc(sizeof(t_node));
if (!temp)
{
perror("Erreur d'allocation de memoire");
exit(EXIT_FAILURE);
}
temp->data = data;
temp->next = NULL;
return (temp);
}
Ajout et Affichage de la Liste
void insert_tail(t_node **head, t_node *new)
{
t_node *current;
if (!head || !new)
return;
if (*head == NULL)
{
*head = new;
return;
}
current = *head;
while (current->next != NULL)
current = current->next;
current->next = new;
}
void print_list(t_node *head)
{
t_node *current;
current = head;
while (current)
{
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
Intégration de delete_node
void delete_node(t_node **head, int value)
{
t_node *current;
t_node *prev;
if (!head || !*head)
return;
// Si le nœud à supprimer est le head
if ((*head)->data == value)
{
current = *head;
*head = (*head)->next;
free(current);
return;
}
prev = *head;
current = (*head)->next;
while (current)
{
if (current->data == value)
{
prev->next = current->next;
free(current);
return;
}
prev = current;
current = current->next;
}
}
Programme Principal (main)
int main(void)
{
t_node *head = NULL;
// Création de la liste
insert_tail(&head, new_node(10));
insert_tail(&head, new_node(20));
insert_tail(&head, new_node(30));
insert_tail(&head, new_node(40));
insert_tail(&head, new_node(50));
printf("Liste avant suppression:\n");
print_list(head);
// Suppression d'un élément
delete_node(&head, 30); // Supprime le nœud contenant 30
printf("Liste après suppression de 30:\n");
print_list(head);
// Suppression d'un élément inexistant
delete_node(&head, 100); // Aucune modification attendue
printf("Liste après tentative de suppression de 100 (inexistant):\n");
print_list(head);
// Suppression du premier élément
delete_node(&head, 10); // Supprime le head
printf("Liste après suppression de 10 (head):\n");
print_list(head);
// Libération de la mémoire
t_node *current;
t_node *next_node;
current = head;
while (current)
{
next_node = current->next;
free(current);
current = next_node;
}
return (0);
}
Cas Limites et Gestion des Erreurs
-
Liste Vide (
head == NULL
):- La fonction ne fait rien si la liste est vide.
-
Suppression du Head:
- Vérification spécifique pour mettre à jour correctement le
head
.
- Vérification spécifique pour mettre à jour correctement le
-
Valeur Non Présente dans la Liste:
- Si la valeur n’est pas trouvée, la liste reste inchangée.
-
Liste à un Seul Nœud:
- La fonction fonctionne correctement si le nœud unique est supprimé. Le
head
devientNULL
.
- La fonction fonctionne correctement si le nœud unique est supprimé. Le
Comparaison avec d’Autres Fonctions
-
Suppression en Tête:
- Supprimer le premier élément est un cas particulier de cette fonction.
- La suppression d’un nœud spécifique ajoute de la complexité car il faut parcourir la liste.
-
Complexité:
- Temps: O(n), car il faut parcourir la liste pour trouver le nœud.
- Espace: O(1), car aucune mémoire supplémentaire significative n’est utilisée.
Résultat attendu
Liste initiale :
10 -> 20 -> 30 -> 40 -> 50 -> NULL
Après suppression de 30 :
10 -> 20 -> 40 -> 50 -> NULL
Après tentative de suppression de 100 (inexistant) :
10 -> 20 -> 40 -> 50 -> NULL
Après suppression de 10 (head) :
20 -> 40 -> 50 -> NULL
Conclusion: La fonction delete_node
est une opération essentielle pour les listes chaînées. Elle gère efficacement les cas limites et s’intègre facilement dans une bibliothèque de manipulation de listes.