وزارة اﻟﺗﻌﻠﯾم اﻟﻌﺎﻟﻲ و اﻟﺑﺣث اﻟﻌﻠﻣﻲ
République Algérienne Démocratique et Populaire
Ministère de l’Enseignement Supérieur et de la Recherche Scientifique
Université Abou Bekr Belkaïd
ﺟﺎﻣﻌﺔ أﺑﻮ ﺑﻜﺮ ﺑﻠﻘﺎ ﯾﺪ
Tlemcen
ﺗﻠﻤﺴﺎن
Faculté des Sciences
ﻛﻠﯿﺔ اﻟﻌﻠﻮم
Concours d’accès en 3ème cycle DOCTORAT LMD en informatique
Option : «Réseaux et Systèmes Distribués»
Epreuve Algorithmique - Durée : 1 heure 30 min
Exercice 1 : (2 points)
Ecrire une fonction EgalArbre (Arbre A, Arbre B): booléen permettant de tester l’égalité de
deux arbres binaires.
Exercice 2 : (7 points)
1. Ecrire un algorithme itératif qui permet de modifier les positions des éléments d’un tableau
d’entiers T de taille N pour que les éléments pairs soit classés après les éléments impairs.
(Vous n’avez pas le droit d’utiliser d'autre structure de données).
2. Donner la version récursive de cet algorithme.
PS : l’indice du premier élément du tableau est 1.
Exercice 3 : (8 points)
On dispose d’une liste chainée triée par ordre croissant sur le champ entier val :
liste
val suivant
1. Ecrire une procédure supprimeDoublons (donnée/résultat liste : adresse de maillon
d'entier) qui supprime les doublons dans une liste chaînée triée d’entiers.
2. Ecrire une procédure insèreDansListeTriée (donnée/résultat liste : adresse de maillon
d'entier, donnée val : entier) qui insère un élément val dans une liste chaînée triée d’entiers (la
liste chaînée obtenue doit être triée).
3. En utilisant la procédure précédente, écrire une nouvelle procédure insèreListe
(donnée/résultat listeTriée : adresse de maillon d'entier, donnée listeNonTriée : adresse de
maillon d'entier) qui insère tous les éléments de la liste chaînée listeNonTriée dans la liste
chaînée triée listeTriée.
Exercice 4 : (3 points)
1. Que calcule l’algorithme suivant ? (justifiez votre réponse).
variables N, M, res : entiers naturels
début
Entrer (N, M)
res=0
Tantque (N != 0) faire
si ((N mod 2) != 0) alors
res=res + M
finsi
N=N div 2
M=M * 2
Fin Tantque
Afficher (res)
Fin
Rappelons que « a div b » et « a mod b » permettent respectivement de récupérer le quotient et le
reste de la division euclidienne de a par b.
2. Quelle est la complexité de l’algorithme précédent ?
Exercice 1 : (2 points)
Ecrire une fonction EgalArbre (Arbre A, Arbre B): booléen permettant de tester l’égalité de deux arbres binaires.
Fonction EgalArbre (Arbre A, Arbre B): booléen
si (( A==NULL) && (B==NULL)) retourner (vrai);
sinon
si ((A!=NULL) &&(B!=NULL))
si((A->Element==B->Element) && EgalArbre(A->Gauche, B->Gauche) && EgalArbre(A->Droit, B->Droit))
retourner vrai;
sinon retourner faux;
finsi
sinon retourner (faux);
fin si
0,25 2 arbres vides, retourner vrai
0,5 L’une des 2 arbres est vide, retourner faux
1 Les 2 arbres non vides. 0,5 si il y a uniquement les 2 appels récursifs (il faut les deux),
retourner vrai
0,25 Eléments différents ou hauteur différente, retourner faux
Exercice 2 (7 points) :
1-Ecrire un algorithme itératif qui permet de modifier les positions des éléments d’un tableau d’entiers T de taille N pour
que les éléments pairs soit classés après les éléments impairs. (Vous n’avez pas le droit d’utiliser d’autre structure de
données).
2-Donner la version récursive de cet algorithme.
1) Algorithme de classement (2,5 pts)
Debut
i=1;
j=N;
Tant que (i< j) faire (0,25 pt)
Tant que (T[i] est impair) et (i< j) faire (0,5 pt)
i=i+1;
Fin tant que
Tant que (T[j] est pair) et (i<j) faire (0,5 pt)
j=j-1;
Fin tant que
Si (i< j) alors (1,25 pt)
X:=T[i];
T[i]:=T[j];
T[j]:=X;
i=i+1;
j=j-1;
Finsi
Fin Tant Que
FIN
2) Appel Classement (T, 1, N) (0,25 pt)
Procedure Classement (T, i, j) (4,5 pts)
Si (i<j) alors
si (T[i] est pair) et (T[j] est impair) alors (1,25 pt)
X:=T[i];
T[i]:=T[j];
T[j]:=X;
retourner Classement(T,i+1,j-1)
Finsi
si (T[i] est impair) et (T[j] est pair) alors retourner Classement(T,i+1,j-1) Finsi (1 pt)
si (T[i] est impair) et (T[j] est impair) alors retourner Classement(T,i+1,j) Finsi (1 pt)
si (T[i] est pair) et (T[j] est pair) alors retourner Classement(T,i,j-1) Finsi (1 pt)
Fin
Exercice 2 : (8 points)
On dispose d’une liste chainée triée par ordre croissant sur le champ entier val :
liste
val suivant
1. Ecrire une procédure supprimeDoublons (donnée/résultat liste : adresse de maillon d'entier) qui supprime les
doublons dans une liste chaînée triée d’entiers.
Procédure supprimeDoublons (donnée/résultat liste : adresse de maillon d'entier)
Variable
ptCourant, ptPrécédent : adresse de maillon d'entier // pour parcourir la liste chaînée.
valCourant : entier // la valeur courante dans la liste chaînée.
Début
Si liste != null Alors
// au début, la valeur courante est le contenu du premier maillon
valCourant <- liste*.val
ptPrécédent <- liste
ptCourant <- liste*.suivant
TantQue ptCourant != null Faire
Si ptCourant*.val = valCourant Faire // si on a un doublon....
// ... on le supprime !
ptPrécédent*.suivant <- ptCourant*.suivant
libérer (ptCourant)
ptCourant <- ptPrécédent*.suivant
Sinon
valCourant <- ptCourant*.val
ptPrécédent <- ptCourant
ptCourant <- ptCourant*.suivant
FinSi
FinTantQue
FinSi
FinProcédure
0,25 liste != null
Initialement, 2 pointeurs obligatoires
0,75 valCourant <- liste*.contenu
ptPrécédent <- liste
ptCourant <- liste*.suivant
0,25 TantQue ptCourant != null Faire : parcourir la liste
0,25 ptCourant*.contenu = valCourant : si on a un doublon
// ... on le supprime !
0,75 ptPrécédent*.suivant <- ptCourant*.suivant
libérer (ptCourant)
ptCourant <- ptPrécédent*.suivant
Nouvelle valeur, on avance : valCourant <- ptCourant*.contenu
0,75 ptPrécédent <- ptCourant
ptCourant <- ptCourant*.suivant
2. Ecrire une procédure insèreDansListeTriée (donnée/résultat liste : adresse de maillon d'entier, donnée val : entier)
qui insère un élément val dans une liste chaînée triée d’entiers (la liste chaînée obtenue doit être triée.)
Procédure insèreDansListeTriée (donnée/résultat liste : adresse de maillon d'entier, donnée val : entier)
Variable
ptCourant : adresse de maillon d'entier // Pour parcourir la liste.
ptPrécédent : adresse de maillon d'entier // maillon précédant celui pointé par ptCourant.
m : adresse de maillon d'entier // Pour construire le nouveau maillon à insérer dans la liste chaînée.
Début
// On commence par créer le nouveau maillon à insérer dans la liste chaînée.
allouer (m)
m*.contenu <- val
// Cas liste vide : on crée une liste chaînée de longueur 1.
Si liste = null Alors
m*.suivant <- null.
liste <- m
// Cas où on doit insérer en tête.
Sinon
Si liste*.contenu >= val Alors
m*.suivant <- liste
liste <- m
// Dans les autres cas, on parcourt jusqu'à trouver un élément plus grand ou égal, ou jusqu'à la fin.
Sinon
ptPrécédent <- liste
ptCourant <- liste*.suivant // ci-dessous : attention à l'ordre des conditions
TantQue ptCourant != null ET ptCourant*.contenu < val Faire
ptPrécédent <- ptCourant
ptCourant <- ptCourant*.suivant
FinTantQue
// Puis on insère le nouveau maillon entre les maillons pointés par
// ptPrécédent et ptCourant.
m*.suivant <- ptCourant
ptPrécédent*.suivant <- m
FinSi
FinSi
FinProcédure
0,5 Allouer le maillon allouer (m)
Mettre la valeur dans le maillon m*.contenu <- val
0,5 // Cas liste vide :tester liste vide
m*.suivant <- null. et liste <- m
0,5 // Cas où on doit insérer en tête. liste*.contenu >= val
m*.suivant <- liste et liste <- m
// Dans les autres cas, 2 pointeurs obligatoires
0,5 ptPrécédent <- liste
ptCourant <- liste*.suivant
0,5 Insertion au milieu ou à la fin, condition ptCourant != null ET ptCourant*.contenu < val (l’ordre
est important)
0,5 Avancer dans les 2 pointeurs ptPrécédent <- ptCourant et ptCourant <- ptCourant*.suivant
0,5 insère le nouveau maillon entre les maillons pointés par ptPrécédent et ptCourant
m*.suivant <- ptCourant
ptPrécédent*.suivant <- m
Procédure insèreListe (donnée/résultat listeTriée : adresse de maillon d'entier,
donnée listeNonTriée : adresse de maillon d'entier)
// Insère les éléments de la liste chaînée listeNonTriée dans la liste chaînée triée listeTriée.
// En sortie, listeTriée est triée.
Variable
ptCourant : adresse de maillon d'entier // Pour parcourir la liste chaînée non triée
Début
// on parcourt la liste chaînée non triée et on insère un à un ses éléments dans
// la liste chaînée triée à l'aide de la procédure insèreDansListeTriée.
ptCourant <- listeNonTriée (0,25 pts)
TantQue ptCourant != null Faire (0,25 pts)
insèreDansListeTriée (listeTriée, ptCourant*.val) (0,5 pts)
ptCourant <- ptCourant*.suivant (0,5 pts)
FinTantQue
FinProcédure
Exercice 4 : (3 points)
On vérifie aisément que cet algorithme calcule a * b (en se basant sur la décomposition de l’entier a en binaire). (2 pts)
Complexité Log2(N) (1 pt)