Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
8969348ac0 | |||
71788b9207 | |||
14803e0cbd | |||
c0f05af956 | |||
44bea89d51 | |||
6d40ee3bd5 | |||
6c15013050 | |||
c29c85f70b | |||
a6c33aff45 | |||
c21f357d34 | |||
21a08a1c90 | |||
acf04e1354 | |||
2e4854c148 |
192
Readme.md
Normal file
192
Readme.md
Normal file
@ -0,0 +1,192 @@
|
||||
#### **Exercice 1**
|
||||
|
||||
1. **`function_1(tableau1, tableau2)`** :
|
||||
Dans cette fonction, il y a deux boucles imbriquées : la première parcourt tous les éléments de `tableau1` (de taille \(n\)), et pour chaque élément, la deuxième boucle parcourt `tableau2` (de taille \(m\)).
|
||||
Dans le pire des cas, si aucun élément ne correspond (ou si le `break` n'est jamais atteint), chaque élément de `tableau1` sera comparé à tous les éléments de `tableau2`.
|
||||
Donc, la complexité de cette fonction est \( O(n \cdot m) \).
|
||||
|
||||
2. **`function_2(x)`** :
|
||||
Ici, on a une boucle `while` qui s’exécute \(x\) fois. À chaque itération, on effectue une addition et une décrémentation, qui prennent toutes les deux un temps constant.
|
||||
Du coup, la complexité est proportionnelle à \(x\), donc \( O(x) \).
|
||||
|
||||
3. **`function_3(x)`** :
|
||||
Cette fonction contient uniquement des blocs `if` indépendants, qui s’exécutent chacun au maximum une seule fois. Il n’y a pas de boucle, donc chaque opération est constante.
|
||||
La complexité est donc \( O(1) \), car c’est constant peu importe la valeur de \(x\).
|
||||
|
||||
---
|
||||
|
||||
#### **Exercice 2**
|
||||
|
||||
Pour analyser la complexité de la fonction **`sort_students`**, on décompose chaque étape :
|
||||
|
||||
1. **Boucle externe sur les grades** :
|
||||
La boucle externe parcourt tous les grades des étudiants, soit \( \text{grades\_number} \) itérations.
|
||||
|
||||
2. **Allocation dynamique des notes** :
|
||||
L’allocation du tableau `grades` est faite avec `malloc`, qui est supposée avoir une complexité \( O(1) \). Cela n’affecte donc pas significativement la complexité globale.
|
||||
|
||||
3. **Copie des notes des étudiants** :
|
||||
Dans la boucle interne :
|
||||
```c
|
||||
for(j = 0; j < students_number; j++) {
|
||||
grades[j] = students_array[j][i];
|
||||
}
|
||||
```
|
||||
on copie les notes des \( \text{students\_number} \) étudiants, ce qui prend \( O(\text{students\_number}) \) par itération de la boucle externe.
|
||||
|
||||
4. **Tri des notes avec `bubblesort`** :
|
||||
La fonction `bubblesort` trie un tableau de taille \( \text{students\_number} \), avec une complexité \( O(\text{students\_number}^2) \).
|
||||
|
||||
5. **Trouver le rang de chaque étudiant** :
|
||||
Ensuite, dans cette boucle interne :
|
||||
```c
|
||||
for(j = 0; j < students_number; j++) {
|
||||
students_rank[j][i] = find_rank_student(students_array[j][i], grades, students_number);
|
||||
}
|
||||
```
|
||||
on appelle `find_rank_student` pour chaque étudiant. Cette fonction effectue :
|
||||
- Un tri par bulles \( O(\text{students\_number}^2) \),
|
||||
- Une recherche pour trouver le rang, qui prend \( O(\text{students\_number}) \).
|
||||
|
||||
Donc, chaque appel à `find_rank_student` a une complexité totale de \( O(\text{students\_number}^2) \), et cette fonction est appelée \( \text{students\_number} \) fois par itération de la boucle externe. Cela donne une complexité \( O(\text{students\_number}^3) \) par itération de la boucle externe.
|
||||
|
||||
6. **Libération de mémoire** :
|
||||
Enfin, la mémoire allouée pour `grades` est libérée avec `free`, ce qui est une opération \( O(1) \).
|
||||
|
||||
### Complexité totale :
|
||||
La boucle externe s’exécute \( \text{grades\_number} \) fois, et la partie la plus coûteuse de la boucle interne est \( O(\text{students\_number}^3) \). La complexité globale de la fonction est donc :
|
||||
\[
|
||||
O(\text{grades\_number} \cdot \text{students\_number}^3)
|
||||
\]
|
||||
|
||||
### Conclusion :
|
||||
La fonction **`sort_students`** a une complexité algorithmique de
|
||||
\[
|
||||
O(\text{grades\_number} \cdot \text{students\_number}^3)
|
||||
\]
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
#### **Exercice 3**
|
||||
|
||||
|
||||
### **Algorithme proposé**
|
||||
|
||||
1. **Tri des sous-dimensions** :
|
||||
- Si on est sur un tableau 1D (le plus bas niveau), on le trie avec un tri par insertion.
|
||||
|
||||
2. **Calcul des sommes des sous-dimensions** :
|
||||
- Pour chaque sous-tableau, on calcule la somme des valeurs pour s’en servir comme critère de tri.
|
||||
|
||||
3. **Tri des sous-dimensions par leurs sommes** :
|
||||
- On trie les sous-dimensions avec un tri par insertion basé sur les sommes calculées.
|
||||
|
||||
4. **Répétition pour les autres dimensions** :
|
||||
- On applique ces étapes de façon récursive à chaque niveau du tableau.
|
||||
|
||||
|
||||
|
||||
### **Implémentation**
|
||||
|
||||
Voici l'algorithme en Python :
|
||||
|
||||
```python
|
||||
# Fonction pour trier un tableau 1D avec un tri par insertion
|
||||
def insertion_sort(arr):
|
||||
for i in range(1, len(arr)):
|
||||
key = arr[i]
|
||||
j = i - 1
|
||||
# Déplacement des éléments plus grands que key
|
||||
while j >= 0 and arr[j] > key:
|
||||
arr[j + 1] = arr[j]
|
||||
j -= 1
|
||||
arr[j + 1] = key
|
||||
|
||||
# Fonction pour trier un tableau multidimensionnel récursivement
|
||||
def recursive_sort(T):
|
||||
# Si c'est un tableau 1D, on le trie
|
||||
if not isinstance(T[0], list):
|
||||
insertion_sort(T)
|
||||
return T
|
||||
|
||||
# Trier chaque sous-dimension
|
||||
for i in range(len(T)):
|
||||
T[i] = recursive_sort(T[i])
|
||||
|
||||
# Calculer les sommes des sous-dimensions
|
||||
sums = [sum(sum(val) if isinstance(val, list) else val for val in sublist) for sublist in T]
|
||||
|
||||
# Trier les sous-dimensions en fonction de leurs sommes
|
||||
for i in range(1, len(T)):
|
||||
key_sum = sums[i]
|
||||
key_sublist = T[i]
|
||||
j = i - 1
|
||||
while j >= 0 and sums[j] > key_sum:
|
||||
sums[j + 1] = sums[j]
|
||||
T[j + 1] = T[j]
|
||||
j -= 1
|
||||
sums[j + 1] = key_sum
|
||||
T[j + 1] = key_sublist
|
||||
|
||||
return T
|
||||
|
||||
# Exemple avec un tableau 2D
|
||||
tableau = [[0, 3, 2], [9, 4, 5], [4, 1, 3]]
|
||||
resultat = recursive_sort(tableau)
|
||||
print(resultat) # Résultat attendu : [[0, 2, 3], [1, 3, 4], [4, 5, 9]]
|
||||
```
|
||||
|
||||
|
||||
### **Exemple d’exécution**
|
||||
|
||||
Prenons le tableau suivant :
|
||||
\[ [ [0, 3, 2], [9, 4, 5], [4, 1, 3] ] \]
|
||||
|
||||
1. **Trier chaque ligne** :
|
||||
- Première ligne : \( [0, 3, 2] \rightarrow [0, 2, 3] \)
|
||||
- Deuxième ligne : \( [9, 4, 5] \rightarrow [4, 5, 9] \)
|
||||
- Troisième ligne : \( [4, 1, 3] \rightarrow [1, 3, 4] \)
|
||||
\[
|
||||
[ [0, 2, 3], [4, 5, 9], [1, 3, 4] ]
|
||||
\]
|
||||
|
||||
2. **Calculer les sommes** :
|
||||
- \( [0, 2, 3] \rightarrow 5 \)
|
||||
- \( [4, 5, 9] \rightarrow 18 \)
|
||||
- \( [1, 3, 4] \rightarrow 8 \)
|
||||
|
||||
3. **Trier les lignes en fonction des sommes** :
|
||||
\[
|
||||
[ [0, 2, 3], [1, 3, 4], [4, 5, 9] ]
|
||||
\]
|
||||
|
||||
|
||||
### **Complexité**
|
||||
|
||||
#### Analyse :
|
||||
|
||||
1. **Tri des tableaux 1D** :
|
||||
- Pour \( M \) éléments, le tri par insertion a une complexité de \( O(M^2) \).
|
||||
|
||||
2. **Tri des sous-tableaux (dimensions \( N > 1 \))** :
|
||||
- Chaque sous-tableau contient \( M^{N-1} \) éléments. Trier ces sous-tableaux coûte \( O(M^{N-1} \cdot M^{N-1}) = O(M^{2(N-1)}) \).
|
||||
|
||||
3. **Calcul des sommes** :
|
||||
- Calculer les sommes pour \( M^{N-1} \) sous-tableaux coûte \( O(M^N) \).
|
||||
|
||||
4. **Complexité totale** :
|
||||
- L'algorithme s’applique de façon récursive sur \( N \) dimensions. La partie dominante vient du tri des sous-tableaux les plus grands :
|
||||
\[
|
||||
T(N, M) = O(M^{2N-2})
|
||||
\]
|
||||
|
||||
|
||||
|
||||
### **Conclusion**
|
||||
|
||||
- - La complexité globale est
|
||||
\[
|
||||
O(M^{2N-2})
|
||||
\]
|
Loading…
Reference in New Issue
Block a user