Skip to content
Snippets Groups Projects
Commit 2b9b0316 authored by paul.albuquer's avatar paul.albuquer
Browse files

updated lesson 5 to version 2020-21

parent 12850f55
No related branches found
No related tags found
No related merge requests found
# Algorithmique et structures de données 2019-20 # Algorithmique et structures de données 2020-21
Contenu du cours 5 du 16.10.2019 Contenu du cours 5 du 14.10.2020
****** ******
## Type composé : `struct` ## Le tri par insertion
- **Exemple des fractions** - Algorithme appliqué au tableau: **4 7 6 1 2**
- On considère une structure pour stocker des fractions : - 1ère étape : 4 **7** 6 1 2
```C - trouver la position `pos` de 7 dans le sous-tableau trié à 1 élément : **4**
struct _fraction { - décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
int num; - insérer l'élément 7 en position `pos=1`
int den;
} fraction; - 2ème étape : 4 7 **6** 1 2
``` - trouver la position `pos` de 6 dans le sous-tableau trié à 2 éléments : **4 7**
- On aimerait aussi définir les opérations arithmétiques associées ou utilitaires : - décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
```C - insérer l'élément 6 en position `pos=1`
void print(fraction frac);
int pgcd(int n,int m); - 3ème étape : 4 6 7 **1** 2
void reduire(fraction* frac); - trouver la position `pos` de 1 dans le sous-tableau trié à 3 éléments : **4 6 7**
fraction fraction_build(int num,int den); - décaler de 1 les éléments de la position `pos=0` à la fin du sous-tableau
fraction add(fraction frac1,fraction frac2); - insérer l'élément 1 en position `pos=0`
fraction add1(int n,fraction frac);
fraction add2(fraction frac,int n); - 4ème étape : 1 4 6 7 **2**
void add_inplace(fraction* frac1,fraction frac2); - trouver la position `pos` de 2 dans le sous-tableau trié à 4 éléments : **1 4 6 7**
fraction sub(fraction frac1,fraction frac2); - décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
fraction sub1(int n,fraction frac); - insérer l'élément 2 en position `pos=1`
fraction sub2(fraction frac,int n);
void sub_inplace(fraction* frac1,fraction frac2); - On obtient le tableau trié: **1 2 4 6 7**
fraction mult(fraction frac1,fraction frac2);
fraction mult1(int n,fraction frac); ## Tri à bulles
fraction mult2(fraction frac,int n);
void mult_inplace(fraction* frac1,fraction frac2); - Algorithme appliqué au tableau **4 7 6 2 1**
fraction divise(fraction frac1,fraction frac2); - Principe : on parcours le tableau depuis et on permute les éléments successifs s'ils sont dans le désordre
fraction divise1(int n,fraction frac); **4 7** 6 2 1
fraction divise2(fraction frac,int n); 4 **7 6** 2 1
void divise_inplace(fraction* frac1,fraction frac2); 4 6 **7 2** 1
fraction puiss(fraction frac,int n); 4 6 2 **7 1**
float reel(fraction frac); 4 6 2 1 7
``` A la fin de cette traversée, le plus grand élément se trouve en dernière position.
- Quelques implémentations de fonctions
```C - On applique à nouveau ce principe, mais sur le tableau allant de la 1ère à l'avant-dernière case du tableau
void reduire(fraction* frac) { **4 6** 2 1 7
if (0 == frac­>num) { 4 **6 2** 1 7
frac­>den = 1; 4 2 **6 1** 7
} else { 4 2 1 6 7
int gcd = pgcd(abs(frac­>num),frac­>den);
frac­>num /= gcd; - Et ainsi de suite ...
frac­>den /= gcd;
} - En 4 étapes nécessitant 4, puis 3, puis 2, et finalement 1, opérations de comparaison-échange, on obtient un tableau trié.
} Donc en 4+3+2+1 = 5**·**4/2 = 10 opérations, on a un tableau trié.
fraction fraction_build(int num,int den) { - Plus généralement, un tableau à N éléments se trie en N(N-1)/2 opérations avec le tri à bulles.
assert(den != 0);
int sign = den/abs(den); ## Type composé : `struct`
fraction res = {sign*num,sign*den};
reduire(&res);
return res;
}
fraction add(fraction frac1,fraction frac2) {
return fraction_build(
frac1.num*frac2.den+frac1.den*frac2.num,
frac1.den*frac2.den
);
}
fraction add1(int n,fraction frac) {
return add(fraction_build(n,1),frac);
}
fraction add2(fraction frac,int n,) {
return add1(n,frac);
}
void add_inplace(fraction* frac1,fraction frac2) {
*frac1 = add(*frac1,frac2);
}
fraction puiss(fraction frac,int n) {
fraction prod = fraction_build(1,1);
for (int i=1;i<=abs(n);i++) {
prod = mult(prod,frac);
}
if (n < 0) {
prod = divise1(1,prod);
}
return prod;
}
```
- **Exemple des chaînes de caractères** - **Exemple des chaînes de caractères**
...@@ -134,7 +99,7 @@ Contenu du cours 5 du 16.10.2019 ...@@ -134,7 +99,7 @@ Contenu du cours 5 du 16.10.2019
ch­>len = -­1; ch­>len = -­1;
} }
``` ```
- Illustration - **Illustration**
![Deep vs. shallow copy](./figures/fig_string_deep_shallow_copy.png) ![Deep vs. shallow copy](./figures/fig_string_deep_shallow_copy.png)
...@@ -159,44 +124,3 @@ Contenu du cours 5 du 16.10.2019 ...@@ -159,44 +124,3 @@ Contenu du cours 5 du 16.10.2019
![Illustration](./figures/fig_recursivite_factorielle.png) ![Illustration](./figures/fig_recursivite_factorielle.png)
- Exemple du PGCD
Algorithme d'Euclide pour le PGCD de 42 et 27
> 42 = 27·1 + 15
> 27 = 15·1 + 12
> 15 = 12·1 + 3
> 12 = 3·4 + 0
PGCD(42,27)=PGCD(27,15)=PGCD(15,12)=PGCD(12,3)=3
```C
int pgcd(int n,int m) {
if (n%m > 0) {
return pgcd(m,n%m);
} else {
return m;
}
}
```
![Illustration de la récursivité pour l'algorithme d'Euclide](./figures/fig_recursivite_pgcd_euclide.png)
- Exemple de l'écriture binaire
```C
void binaire(int n) {
printf("%d",n%2);
if (n/2 != 0) {
binaire(n/2);
} else {
printf("\n");
}
// printf("%d",n%2);
}
Binaire(13); // affiche 1 0 1 1 puis un retour à la ligne`
```
> > > $\hspace*{36mm} 2^0 2^1 2^2 2^3$
![Illustration de la récursivité pour l'écriture binaire](./figures/fig_recursivite_binaire.png)
- Que se passe-t-il si on décommente le deuxième `printf` ?
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment