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
Pipeline #14745 passed
# 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;
```
- 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) { - 2ème étape : 4 7 **6** 1 2
assert(den != 0); - trouver la position `pos` de 6 dans le sous-tableau trié à 2 éléments : **4 7**
int sign = den/abs(den); - décaler de 1 les éléments de la position `pos=1` à la fin du sous-tableau
fraction res = {sign*num,sign*den}; - insérer l'élément 6 en position `pos=1`
reduire(&res);
return res;
}
fraction add(fraction frac1,fraction frac2) { - 3ème étape : 4 6 7 **1** 2
return fraction_build( - trouver la position `pos` de 1 dans le sous-tableau trié à 3 éléments : **4 6 7**
frac1.num*frac2.den+frac1.den*frac2.num, - décaler de 1 les éléments de la position `pos=0` à la fin du sous-tableau
frac1.den*frac2.den - insérer l'élément 1 en position `pos=0`
);
}
fraction add1(int n,fraction frac) { - 4ème étape : 1 4 6 7 **2**
return add(fraction_build(n,1),frac); - 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`
fraction add2(fraction frac,int n,) { - On obtient le tableau trié: **1 2 4 6 7**
return add1(n,frac);
}
void add_inplace(fraction* frac1,fraction frac2) { ## Tri à bulles
*frac1 = add(*frac1,frac2);
}
fraction puiss(fraction frac,int n) { - Algorithme appliqué au tableau **4 7 6 2 1**
fraction prod = fraction_build(1,1); - Principe : on parcours le tableau depuis et on permute les éléments successifs s'ils sont dans le désordre
for (int i=1;i<=abs(n);i++) { **4 7** 6 2 1
prod = mult(prod,frac); 4 **7 6** 2 1
} 4 6 **7 2** 1
if (n < 0) { 4 6 2 **7 1**
prod = divise1(1,prod); 4 6 2 1 7
} A la fin de cette traversée, le plus grand élément se trouve en dernière position.
return prod;
} - 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** - **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