Vous êtes sur la page 1sur 4

Université de Ghardaia 2022-2023

Département des Mathématiques et d’Informatique 18/12/2022


2ème Année Informatique (Semestre 3) Durée : 01H30
Examen partiel – corrigé type
Algorithmique et Structures de Données 3
✓ Les documents et téléphones portables sont interdits.

Exercice 1 : (04,50 points)


Supposons que vous implémentiez une table de symbole en utilisant un r-way trie avec le type de
données suivant :
public class RwayTrie {
private final int r;
private Node root;
public RwayTrie(int r) {
this.r = r;
root = null;
}
private class Node {
private final int value;
private Node[] next;
private Node(int value) {
this.value = value;
this.next = new Node[r];
}
}
...
}

En utilisant un modèle de coût mémoire 64-bits :

1. Analyser l'usage de l'espace mémoire d'un objet Node.


2. Analyser l'usage de l'espace mémoire quand un objet Node est construit. Écrivez votre réponse
en fonction de r.

Remarque : Un extra espace mémoire de 8 octets pour les classes internes est nécessaire seulement
pour les objets non-statiques.

Solution : Exercice 1 : (04,50 points)


1. Analyser l'usage de l'espace mémoire d'un objet Node. (2.50 pts)

L'objet «Node» utilise 40 octets tel qu’illustré dans la figure suivante :

Node
16 Entête objet
8 Entête inner class
4 value
8 next
4 Padding
40 octets

Page 1/4
2. Analyser l'usage de l'espace mémoire quand un objet Node est construit. Écrivez votre réponse
en fonction de r. (2.00 pts)

Quand un objet «Node» est construit, on doit prendre en compte l’espace mémoire d’un
tableau de Node de taille r égale à 24 + 8r. Soit une taille totale de 64 + 8 r.

Exercice 2 : (08,50 points)


Décrivez le temps d'exécution dans le pire des cas des codes suivants en utilisant la notation
« Grand Oh » en fonction de 𝒏.
N.B. :
• Vous devez donner la limite la plus étroite possible.
• Pour les fonctions itératives trouver d’abord une formule (somme) pour exprimer le temps
d’exécution puis établir son ordre de grandeur.
• Pour les fonctions récursives construire d’abord une relation de récurrence ensuite résoudre
cette relation pour établir l’ordre de grandeur de sa solution.

a. b.
void f1(int n) { void f2(int n) {
for(int i=0; i < n; i++) { for(int i=0; i < n; i++) {
for(int j=0; j < n; j++) { for(int j=0; j < 10; j++) {
for(int k=0; k < n; k++) { for(int k=0; k < n; k++) {
for(int m=0; m < n; m++) { for(int m=0; m < 10; m++) {
System.out.println("!"); System.out.println("!");
}}}} }}}}
} }
c. d.
int f3(int n) { int f4(int n) {
int sum = 73; if (n < 10) {
for(int i=0; i < n; i++) { System.out.println("!");
for(int j=i; j >= 5; j--) { return n+3;
sum--; } else {
} return f4(n-1) + f4(n-1);
} }
return sum; }
}
e.
int f5(int n) {
if (n < 10) {
System.out.println("!");
return n+3;
} else {
return f5(n-1) + 1;
}
}

Page 2/4
Solution : Exercice 2 : (1.5 + 1.5 + 1.5 + 2 + 2)

a. O(n4) b. O(n2) c. O(n2) d. O(2n) e. O(n)

a.
𝑛−1 𝑛−1 𝑛−1 𝑛−1

𝑎(𝑛) = ∑ ∑ ∑ ∑ 1 = 𝑛4 = 𝑂(𝑛4 )
𝑖=0 𝑗=0 𝑘=0 𝑚=0

b.
𝑛−1 10 𝑛−1 10

𝑏(𝑛) = ∑ ∑ ∑ ∑ 1 = 100 𝑛2 = 𝑂(𝑛2 )


𝑖=0 𝑗=0 𝑘=0 𝑚=0

c.
𝑛−1 𝑖 𝑛−1 𝑛−1 𝑛−1
𝑛(𝑛 − 1)
𝑐(𝑛) = ∑ ∑ 1 = ∑(𝑖 − 5 + 1) = ∑ 𝑖 − ∑ 4 = − 4 𝑛 = 𝑂(𝑛2 )
2
𝑖=0 𝑗=5 𝑖=0 𝑖=0 𝑖=0

d.
1 𝑠𝑖 𝑛 < 10
𝑑(𝑛) = {
2 𝑑(𝑛 − 1) + 1 𝑠𝑖𝑛𝑜𝑛

d(n) = 2d(n − 1) + 1
= 2(2d(n − 2) + 1) + 1 = 4 d(n − 2) + 3
= 4(2(d(n − 2) + 1) + 3 = 8 d(n − 3) + 7 = 23 d(n − 3) + 23 − 1

= 2𝑖 d(n − i) + 2𝑖 − 1

= 2𝑛−9 d(9) + 2𝑛−9 − 1


2𝑛
= 2𝑛−8 − 1 = 8 − 1 = 𝑂(2𝑛 )
2

e.

1 𝑠𝑖 𝑛 < 10
𝑒(𝑛) = {
𝑒(𝑛 − 1) + 1 𝑠𝑖𝑛𝑜𝑛

e(n) = e(n − 1) + 1
= e(n − 2) + 2
= e(n − 3) + 3

= e(n − i) + i


= e(9) + n − 9 // i = n-9
= 1 + n − 9 = n − 8 = O(n)

Page 3/4
Exercice 3 : (07,00 points)

Écrire une fonction récursive RecursiveReverse () qui inverse une liste linéaire chaînée. Le code
ne doit faire qu'une seule passe (un seul parcours) sur la liste donnée. Illustrer votre idée à l’aide d’un
exemple.

Solution Exercice 3

Description de la solution (1.50 pts)


Conditions d’arrêt :
• Une liste vide : On renvoie une liste vide
• Une liste contenant un seul nœud : on renvoie ce nœud.
Appel récursif :
On divise la liste en deux parties, le premier nœud et le reste et on procède comme suit :
• Le premier nœud sera le dernier donc il ne pointe nulle part.
• On inverse le reste de la liste récursivement.
• On connecte le dernier nœud de la liste reste avec le premier nœud (le nouveau dernier)
• On renvoie la tête de liste reste comme tête de la liste inverse.

Exemple : (1.00 pt)


Inverse {1, 2, 3}
Division : {1} , {2, 3}
Inverse {2, 3}
Division {2}, {3}
Inverse {3}
Renvoie 3
Connecte {3} à {2} pour avoir {3, 2}
Renvoie 3
Connecte {3, 2} à {1} pour avoir {3, 2, 1}
Renvoie 3

Algorithme (4.50 pts)

public Node RecursiveReverse(Node head) {


if (head == null) return null; // empty list - base case
if (head.next = null) return head ; // a list contains one element - base case
Node nextNode = head.next;
head.next = null;
Node rest = RecursiveReverse(nextNode);
nextNode.next = head;
return rest;
}

Bon courage
Page 4/4

Vous aimerez peut-être aussi