🧠 Exercice 1 : Insertion triée
Énoncé :
Écris une fonction void insert_sorted(Node** head, int value) qui insère un entier
dans une liste chaînée triée de manière croissante, tout en conservant l'ordre.
But : Maîtriser les pointeurs de pointeurs et les insertions dans tous les cas (début, milieu,
fin).
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
typedef Node* liste;
// Fonction pour insérer un élément dans une liste triée
void insert_sorted(liste* head, int value) {
liste p = (liste)malloc(sizeof(Node));
p->data = value;
// Cas 1 : Insertion en début de liste
if (*head == NULL || value < (*head)->data) {
p->next = *head;
*head = p;
// Cas 2 ou 3 : On cherche la position
liste t = *head;
while (t->next != NULL && t->next->data < value) {
t = t->next;
// Maintenant, soit t->next est NULL ? fin, soit ce n'est pas NULL ? milieu
if (t->next == NULL) {
// Cas 3 : Insertion à la fin
t->next = p;
p->next = NULL;
} else {
// Cas 2 : Insertion au milieu
p->next = t->next;
t->next = p;
void afficher_liste(Node* head) {
Node* courant = head;
while (courant != NULL) {
printf("%d", courant->data);
if (courant->next != NULL) {
printf(" -> ");
courant = courant->next;
printf("\n");
}
main() {
liste head = NULL;
// Test des insertions
insert_sorted(&head,5);
insert_sorted(&head,8);
insert_sorted(&head,3);
// Affichage de la liste après insertions
afficher_liste(head);
🧠 Exercice 2 : Suppression des doublons (liste triée)
Énoncé :
Écris une fonction void remove_duplicates(Node* head) qui supprime les doublons dans
une liste triée.
Exemple :
Entrée : 1 -> 1 -> 2 -> 3 -> 3 -> 4
Sortie : 1 -> 2 -> 3 -> 4
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
// Fonction pour créer un nouveau nœud
Node* creer_noeud(int valeur) {
Node* nouveau = (Node*)malloc(sizeof(Node));
nouveau->data = valeur;
nouveau->next= NULL;
return nouveau;
void afficher_liste(Node* tete) {
Node* courant = tete;
while (courant != NULL) {
printf("%d", courant->data);
if (courant->next != NULL) {
printf(" -> ");
courant = courant->next;
printf("\n");
void remove_duplicates(Node* head) {
Node* t=head;
while(t->next!=NULL){
if(t->data==t->next->data){
Node *p = (Node*)malloc(sizeof(Node));
p=t->next;
t->next=p->next;
free(p);
t=t->next;
}
}
main() {
// Création manuelle de chaque nœud
Node* tete = creer_noeud(1);
tete->next = creer_noeud(1);
tete->next->next= creer_noeud(2);
tete->next->next->next = creer_noeud(3);
tete->next->next->next->next = creer_noeud(3);
tete->next->next->next->next->next = creer_noeud(4);
afficher_liste(tete);
remove_duplicates(tete);
afficher_liste(tete);}
🧠 Exercice 4 : Fusion de deux listes triées
Énoncé :
Écris une fonction Node* merge_sorted_lists(Node* l1, Node* l2) qui fusionne deux
listes triées en une seule triée.
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node* next;
} Node;
Node* merge_sorted_lists(Node* l1, Node* l2) {
// Créer une nouvelle tête pour la liste fusionnée
Node* l3 = (Node*)malloc(sizeof(Node));
Node* k = l3; // Pointeur pour parcourir la nouvelle liste
Node* p = l1;
Node* t = l2;
// Fusionner les deux listes
while (p != NULL && t != NULL) {
if (p->data < t->data) {
k->next = p; // Ajouter p à la liste fusionnée
p = p->next; // Avancer dans l1
} else {
k->next = t; // Ajouter t à la liste fusionnée
t = t->next; // Avancer dans l2
k = k->next; // Avancer dans la liste fusionnée
// Si l1 n'est pas encore vide, ajouter le reste de l1
if (p != NULL) {
k->next = p;
// Si l2 n'est pas encore vide, ajouter le reste de l2
if (t != NULL) {
k->next = t;
return l3->next; // Retourner la liste fusionnée (sans le premier élément fictif)
Node* fusionnerListes(Node* l1, Node* l2) {
if (!l1) return l2;
if (!l2) return l1;
Node* resultat = NULL;
if (l1->data < l2->data) {
resultat = l1;
resultat->next = fusionnerListes(l1->next, l2);
} else {
resultat = l2;
resultat->next = fusionnerListes(l1, l2->next);
return resultat;
🧠 Exercice 6 : Trouver le milieu d'une liste
Énoncé :
Écris une fonction Node* find_middle(Node* head) qui retourne le pointeur vers le milieu
de la liste. Si le nombre d’éléments est pair, retourne le 2ème des deux milieux.
Node* find_middle(Node* head) {
if (head == NULL) return NULL; // Si la liste est vide, retourner NULL
// 1. Calculer la longueur de la liste
int length = 0;
Node* temp = head;
while (temp != NULL) {
length++;
temp = temp->next;
// 2. Trouver la position du milieu
int mid_position = length / 2;
temp = head;
// 3. Parcourir à nouveau jusqu'à la position du milieu
for (int i = 0; i < mid_position; i++) {
temp = temp->next;
// Retourner le nœud du milieu
return temp;