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**
- On considère une structure pour stocker des fractions :
```C
struct _fraction {
int num;
int den;
} fraction;
```
- On aimerait aussi définir les opérations arithmétiques associées ou utilitaires :
```C
void print(fraction frac);
int pgcd(int n,int m);
void reduire(fraction* frac);
fraction fraction_build(int num,int den);
fraction add(fraction frac1,fraction frac2);
fraction add1(int n,fraction frac);
fraction add2(fraction frac,int n);
void add_inplace(fraction* frac1,fraction frac2);
fraction sub(fraction frac1,fraction frac2);
fraction sub1(int n,fraction frac);
fraction sub2(fraction frac,int n);
void sub_inplace(fraction* frac1,fraction frac2);
fraction mult(fraction frac1,fraction frac2);
fraction mult1(int n,fraction frac);
fraction mult2(fraction frac,int n);
void mult_inplace(fraction* frac1,fraction frac2);
fraction divise(fraction frac1,fraction frac2);
fraction divise1(int n,fraction frac);
fraction divise2(fraction frac,int n);
void divise_inplace(fraction* frac1,fraction frac2);
fraction puiss(fraction frac,int n);
float reel(fraction frac);
```
- Quelques implémentations de fonctions
```C
void reduire(fraction* frac) {
if (0 == frac­>num) {
frac­>den = 1;
} else {
int gcd = pgcd(abs(frac­>num),frac­>den);
frac­>num /= gcd;
frac­>den /= gcd;
}
}
fraction fraction_build(int num,int den) {
assert(den != 0);
int sign = den/abs(den);
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;
}
```
- Algorithme appliqué au tableau: **4 7 6 1 2**
- 1ère étape : 4 **7** 6 1 2
- trouver la position `pos` de 7 dans le sous-tableau trié à 1 élément : **4**
- décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
- insérer l'élément 7 en position `pos=1`
- 2ème étape : 4 7 **6** 1 2
- trouver la position `pos` de 6 dans le sous-tableau trié à 2 éléments : **4 7**
- décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
- insérer l'élément 6 en position `pos=1`
- 3ème étape : 4 6 7 **1** 2
- trouver la position `pos` de 1 dans le sous-tableau trié à 3 éléments : **4 6 7**
- décaler de 1 les éléments de la position `pos=0` à la fin du sous-tableau
- insérer l'élément 1 en position `pos=0`
- 4ème étape : 1 4 6 7 **2**
- trouver la position `pos` de 2 dans le sous-tableau trié à 4 éléments : **1 4 6 7**
- décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
- insérer l'élément 2 en position `pos=1`
- On obtient le tableau trié: **1 2 4 6 7**
## Tri à bulles
- Algorithme appliqué au tableau **4 7 6 2 1**
- Principe : on parcours le tableau depuis et on permute les éléments successifs s'ils sont dans le désordre
**4 7** 6 2 1
4 **7 6** 2 1
4 6 **7 2** 1
4 6 2 **7 1**
4 6 2 1 7
A la fin de cette traversée, le plus grand élément se trouve en dernière position.
- On applique à nouveau ce principe, mais sur le tableau allant de la 1ère à l'avant-dernière case du tableau
**4 6** 2 1 7
4 **6 2** 1 7
4 2 **6 1** 7
4 2 1 6 7
- Et ainsi de suite ...
- 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é.
- Plus généralement, un tableau à N éléments se trie en N(N-1)/2 opérations avec le tri à bulles.
## Type composé : `struct`
- **Exemple des chaînes de caractères**
......@@ -134,7 +99,7 @@ Contenu du cours 5 du 16.10.2019
ch­>len = -­1;
}
```
- Illustration
- **Illustration**
![Deep vs. shallow copy](./figures/fig_string_deep_shallow_copy.png)
......@@ -159,44 +124,3 @@ Contenu du cours 5 du 16.10.2019
![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