Académique Documents
Professionnel Documents
Culture Documents
Exercices Corrig
Exercices Corrig
Exercices Corrigés
Mohamed El Ansari
Semestre 4
Printemps 2013
Ce document propose des exercices corrigés en algorithmique & structures de données
pour la filière Sciences Mathématiques et Informatique (SMI). Le cours est dispensé en semstre 4.
1 Exercices proposés 3
1.1 Exercice 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Exercice 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 Exercice 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 Exercice 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 Exercice 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6 Exercice 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.7 Exercice 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.8 Exercice 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.9 Exercice 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1 Exercice 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Exercice 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Exercice 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.4 Exercice 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Exercice 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.6 Exercice 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.7 Exercice 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.8 Exercice 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.9 Exercice 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2
Chapitre 1
Exercices proposés
1.1 Exercice 1
La suite de Fibonacci est une série d’entiers : 0, 1, 1, 2, 3, 5, 8, 21, 34, 55, 89 ...
Chaque élément de la série est la somme des deux éléments qui le précèdent. La suite de
Fibonacci est définie comme suit :
(
N si N = 0, 1
F ib(N ) =
F ib(N − 2) + F ib(N − 1) si N >1
1.2 Exercice 2
1. Donner une fonction récursive som permettant de calculer :
1 4 9
0+ + + + ...
2 3 4
Exemples :
som(0)=0, som(1)=0+(1/2), som(2)=0+(1/2)+(4/3), som(3)=0+(1/2)+(4/3)+(9/4)
2. Donner sa complexité en nombre d’additions.
1.3 Exercice 3
1. Donner une fonction recursive SOM permettant de calculer la somme suivante :
1 1 1 1 1
1− + − + − + ....
2 3 4 5 6
Exemple : SOM(1)=1, SOM(2)=1- 21 , SOM(3)=1- 12 + 1
3
La fonction SOM calcule SOM(N) pour tout N >= 1.
2. Donner la complexité de la fonction SOM. On tient compte uniquement des opérations
d’additions et soustractions.
3
1.4. EXERCICE 4 CHAPITRE 1. EXERCICES PROPOSÉS
1.4 Exercice 4
On se donne une liste chaı̂née L, d’entiers, dont les noeuds ayant la structure suivante :
struct sliste {
int data;
struct sliste * suiv;
};
typedef struct sliste Liste;
1.5 Exercice 5
Considérons une pile de réels dont les noeuds ayant la structure suivante :
1. Donner une fonction Empiler qui permet d’empiler un réel val dans une pile P.
2. Supposons que nous nous disposons des déclarations suivantes dans un programme principal :
UnePile * A = NULL;
float a = 9.5;
Donner l’instruction permettant d’appeler la fonction Empiler afin d’empiler la valeur de a
dans la pile A.
1.6 Exercice 6
1. Donner une fonction recursive permettant de calculer le nombre d’éléments d’une liste.
Donner sa complexité.
2. Donner une fonction permettant de fusionner deux listes qui sont triées par ordre croissant.
La liste résultante doit être elle même triée par ordre croissant. La fonction reçoit deux listes
triées et retourne une liste triée. Les deux listes passées en paramètres ne doivent pas être
conservées par la fonction : il est encouragé de réutiliser leurs maillons pour venir les chaı̂ner
au bon endroit dans la liste chaniée résultat.
1.7 Exercice 7
Supposons que nous disposons d’une pile P d’entiers. Nous souhaitons renverser les éléments de
P en utilisant deux méthodes différentes :
1. Donner une fonction en C permettant de renverser les éléments de P en utilisant une pile
auxilaire (méthode 1).
2. Donner une fonction en C permettant de renverser les éléments de P en utilisant une file
auxilaire (méthode 2).
Exemple de renversion : la pile contenant les éléments 2,3,-1,0,9 deviendra 9,0,-1,3,2 après
renversion.
1.8 Exercice 8
On suppose que nous nous disposons d’une liste chaı̂née d’entiers qui peut être vide ou non vide
(cas général). Nous souhaitons implémenter les fonctions ci-dessous.
1. Donner une fonction qui a pour but le tri des éléments d’une liste par ordre décroissant. La
fonction doit agir directement sur la liste fournie en arguement.
2. Donner une fonction qui insère un entier dans une liste triée par ordre décroissant. La
fonction doit chercher la position convenable pour l’insertion de l’entier afin que la liste
reste triée par ordre décroissant. La fonction doit agir directement sur la liste fournie en
argument. La fonction reçoit un entier et la création du noeud s’effectuera dans la fonction.
3. Ecrire une fonction qui reçoit deux listes L1 et L2 et retourne 1 si la liste L1 est un début
de la liste L2 et 0 sinon.
4. En déduire une fonction qui retourne 1 si la liste L1 est une partie de la liste L2 et 0 sinon.
1.9 Exercice 9
Supposons que nous nous disposons d’un arbre binaire de recherche (ABR) d’entiers.
1. On souhaite récuperer l’adresse d’une clé (entier stocké dans un noeud de l’ABR). Si la clé
figure dans l’ABR la fonction retourne son adresse, sinon la fonction return 0. Ecrire une
fonction qui retourne l’adresse d’une clé d’un ABR.
2. Ecrire une fonction qui compare deux arbres binaires. La fonction renvoie une valeur nulle
si et seulement si les deux arbres binaires ont la même structure d’arbre et qu’ils portent les
mêmes valeurs aux noeuds qui se correspondent.
2.1 Exercice 1
La suite de Fibonacci est une série d’entiers : 0, 1, 1, 2, 3, 5, 8, 21, 34, 55, 89 ...
Chaque élément de la série est la somme des deux éléments qui le précèdent. La suite de
Fibonacci est définie comme suit :
(
N si N = 0, 1
F ib(N ) =
F ib(N − 2) + F ib(N − 1) si N >1
6
2.2. EXERCICE 2 CHAPITRE 2. SOLUTION DES EXERCICES PROPOSÉS
}
}
3. Est ce que la version recursive est efficace ? Pourquoi ?
la méthode recursive n’est pas efficace puisque il y a redondance dans les calculs.
2.2 Exercice 2
1. Donner une fonction récursive som permettant de calculer :
1 4 9
0+ + + + ...
2 3 4
Exemples :
som(0)=0, som(1)=0+(1/2), som(2)=0+(1/2)+(4/3), som(3)=0+(1/2)+(4/3)+(9/4)
float sum(int n)
{
if (n==0) return 0;
else
return (float) (n*n)/(n+1) + sum(n-1);
}
2.3 Exercice 3
1. float SOM(int n)
{
if (n==1) return 1;
else if (n%2)
return SOM(n-1) + (float)1/n;
else
return SOM(n-1) - (float)1/n;
}
2. T(n=1) = 0
T(n=2) = T(1) + 1 = 1
T(n=3) = T(2) + 1 = 2
.
.
T(n) = n - 1
La complexité est O(n).
2.4 Exercice 4
On se donne une liste chaı̂née L, d’entiers, dont les noeuds ayant la structure suivante :
struct sliste {
int data;
struct sliste * suiv;
};
typedef struct sliste Liste;
/* liste vide */
if (!lis) return elem;
/* Liste vide */
if (!lis) return 0;
Queue = PrecQueue->suiv;
if (Tete->suiv == Queue) { /* liste comporte 2 elemnts */
free(Tete);
free(Queue);
lis = 0;
return lis;
}
else {
/* supprimer tete */
lis = lis->suiv;
free(Tete);
/* supprimer queue */
free(Queue);
PrecQueue->suiv = 0;
return lis;
}
}
Une autre proposition
void * SuppTeteQueue(Liste ** lis)
{
Liste * Tete = *lis, *PrecQueue = *lis, *Queue;
/* Liste vide */
if (!Tete) return 0;
Queue = PrecQueue->suiv;
/* supprimer queue */
free(Queue);
PrecQueue->suiv = 0;
}
}
2.5 Exercice 5
Considérons une pile de réels dont les noeuds ayant la structure suivante :
UnePile *elem = 0;
*P = elem;
}
}
2. Empiler(&A,a);
2.6 Exercice 6
1. Donner une fonction recursive permettant de calculer le nombre d’éléments d’une liste.
Donner sa complexité.
int longueur(Liste L)
{
if (L==NULL) return 0;
else return (1+longueur(L->next));
}
T(n)= 1+T(n-1)=2+T(n-2)=n+T(0)=n.
est en O(n)
2. Donner une fonction permettant de fusionner deux listes qui sont triées par ordre croissant.
La liste résultante doit être elle même triée par ordre croissant. La fonction reçoit deux listes
triées et retourne une liste triée. Les deux listes passées en paramètres ne doivent pas être
conservées par la fonction : il est encouragé de réutiliser leurs maillons pour venir les chaı̂ner
au bon endroit dans la liste chaniée résultat.
/* A function to merge two sorted lists */
struct node *merge (struct node *p, struct node *q)
{
struct node *r=NULL,*temp;
if (p == NULL)
r = q;
else
if(q == NULL)
r = p;
else
{
if (p->data < q->data )
{
r = p;
temp = p;
p = p->link;
temp->link = NULL;
}
else
{
r = q;
temp =q;
q =q->link;
temp->link = NULL;
}
while((p!= NULL) && (q != NULL))
{
if (p->data < q->data)
{
temp->link =p;
p = p->link;
temp =temp->link;
temp->link =NULL;
}
else
{
temp->link =q;
q = q->link;
temp =temp->link;
temp->link =NULL;
}
}
if (p!= NULL)
temp->link = p;
if (q != NULL)
temp->link = q;
}
return( r) ;
}
2.7 Exercice 7
Supposons que nous disposons d’une pile P d’entiers. Nous souhaitons renverser les éléments de
P en utilisant deux méthodes différentes :
1. Donner une fonction en C permettant de renverser les éléments de P en utilisant une pile
auxilaire (méthode 1).
typedef struct stack {
int data;
struct stack *next;
} STACK;
2. Donner une fonction en C permettant de renverser les éléments de P en utilisant une file
auxilaire (méthode 2).
struct queue_node
{
struct queue_node *next;
int data;
};
struct queue
{
struct queue_node *first; // Defiler
struct queue_node *last; //Enfiler
};
while(q.first != NULL)
{
dequeue(&q, &x);
push(Pile,x);
}
}
/*-----------------------DEPILER ---------------*/
{
if (*head==NULL) {/* pile est vide */
fputs("Error: stack underflow\n", stderr);
abort();
} else {
/* depiler un element */
STACK *top = *head;
int value = top->data;
*head = top->next;
free(top);
return value;
}
}
/*--------------- Defiler---------------------------------------*/
return 0;
}
2.8 Exercice 8
#include<stdio.h>
#include<stdlib.h>
printf("\n");
}
if (p->val >= i)
{
p->suiv = elem; elem->suiv = NULL;
}
else
{
elem->suiv = *l;
*l = elem;
}
}
if (debut(l1,l2)) return 1;
l2 = l2->suiv;
}
return 0;
}
/* ************ *********************************** */
/******************************************************* */
main()
{
int i;
noeud * L = 0;
for(i=0; i<9 ; i++)
inserer(&L, rand()%15);
afficher(L);
trier(&L);
afficher(L);
inserertrier(&L, 8);
afficher(L);
inserertrier(&L, -1);
afficher(L);
inserertrier(&L, 89);
afficher(L);
2.9 Exercice 9
#include<stdlib.h>
#include<stdio.h>
// structure arbre
typedef int element_type;
typedef struct tree_node *tree_ptr;
struct tree_node {
element_type element;
tree_ptr left;
tree_ptr right;
};
/* Programme test */
main(){
tree_ptr A=NULL, B=NULL;
A = insert(4, A); A = insert(3, A); A = insert(7, A); A = insert(-2, A);
B = insert(-2, B); B = insert(3, B); B = insert(7, B); B = insert(4,
B);