Vous êtes sur la page 1sur 78

Spé : MP – PSI - TSI

Informatique
au CPGE Marocaines
(Cours/TD)

ZBAKH ABDELALI

- Enseignant-Chercheur à l'ENCG TANGER


- Professeur d’informatique – CPGE Albayrouni TANGER
- Ancien professeur d’informatique - CPGE TANGER (2009-2021)
- Docteur en Informatique, Spécialité Intelligence Artificielle et Big Data.

Tél: (+212) 672 77 09 13


Email : zbakhabdou@gmail.com
Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Table des matières

Série n° 1 : Python -Rappel .............................................................................................. 2

Chapitre 1 : Les algorithmes de tri .................................................................... 6

Chapitre 2 : complexité algorithmique ............................................................ 15

Chapitre 3 : les arbres binaires ........................................................................ 31

Chapitre 4 : Introduction à la théorie des graphes .................................... 42

Chapitre 5 : Algèbre relationnelle................................................................. 53

Chapitre 6: Langage sql ........................................................................................ 63

1 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 1 : Python -Rappel

Fonctions/ Listes/chaînes de caractères/Matrices/POO/Fichiers

Exercice 1 :

Si p est le demi périmètre d’un triangle de côtés a, b et c alors l’aire du triangle est donnée par :

Écrire la fonction Aire qui prend en paramètre quatre nombres p,a,b ,c et qui retourne l’aire d’un triangle.

Exercice 2 :

Écrire 2 fonctions :
—mini (a,b) qui renvoie le minimum entre a et b
—maxi (a,b) qui renvoie le maximum entre a et b

Exercice 3 :

Sur l’intervalle [−1, 0], la fonction f est égale à la fonction affine x→x+1 et sur l’intervalle [0, 2], f est égale à la
fonction affine x→1−x/2

Ecrire la fonction f qui prend en argument un nombre x et qui retourne f(x)

Exercice 4 : Paradoxe des anniversaires

La probabilité pn qu’au moins deux étudiants d’une classe de n étudiants aient leur anniversaire le même jour
de l’année est donnée par la formule :

Écrire une fonction probabilite(n) qui calcule et retourne pn.

Exercice 5 : (4 points) Les coefficients binomiaux (CNC MP2020)


Un coefficient binomial est défini pour deux entiers positifs n et k tels que n≥k. C’est le nombre de parties de k
éléments dans un ensemble de n éléments. On le note : , et sa valeur est calculée par la formule suivante :

Q1- Écrire la fonction fact(p) qui reçoit en paramètre un entier positif p, et qui retourne la valeur de factorielle
p : p! = 1 * 2 * 3 * … * (p-1) * p.
NB : La fonction fact(0) retourne 1
Q2- Écrire la fonction produit(n,k) qui reçoit en paramètres deux entiers positifs n et k tels que n≥k, et qui
retourne la valeur du produit : n * (n-1) * (n-2) * … * (n-(k-1))

2 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Q3- Écrire la fonction binomial(n,k) qui reçoit en paramètres deux entiers positifs n et k tels que n≥k, et qui
retourne la valeur du coefficient binomial
Exemple : La fonction binomial (6, 3) retourne le nombre 20
Q4- Écrire la fonction liste_binomiaux(n) qui reçoit en paramètre un entier positif n, et qui retourne la liste des
coefficients binomiaux tel que : k = 0, 1, 2, 3, …, n
Exemple : La fonction liste_binomiaux (6) retourne la liste [ 1, 6, 15, 20, 15, 6, 1 ]

Exercice 6 :

Écrire une fonction somme(L) qui calcule et retourne la somme des éléments de la liste L (si cette liste
est vide, le résultat renvoyé devra être 0).
Exercice 7 :

Écrire une fonction moyenne(L) qui calcule et retourne la moyenne des éléments de la liste L (cette liste
ne devra pas être vide).

Exercice 8 :

Écrire une fonction variance(L) qui calcule et retourne la variance de la liste L définie par :

Exercice 9 :

Ecrire une fonction smin qui retourne le caractère minimal d’une chaine de caractères passée en paramètre.
Ex : smin(«hello») -> «e»

Exercice 10 :

Ecrire une fonction smax qui retourne le caractère maximal d’une chaine de caractères passée en paramètre.
(smax)
Ex : smax(«hello») -> «o»

Exercice 11 :

Ecrire une fonction wcount qui prend en paramètre une chaine de caractères et retourne le nombre de mots
de cette chaine.
Ex : wcount(‘beauty is a mind thinking way’) -> 6

Exercice 12 :

Ecrire une fonction stri qui prend en paramètre une chaine de caractères et retourne une nouvelle chaine de
caractères MAJSUCULE triée par ordre alphabétique.
Ex : stri(«Top») -> «OPT»

Exercice 13 :

Réaliser une fonction genereListe qui renvoie une liste de 100 nombres entiers tirés au hasard dans l’intervalle
[0,99] (bornes incluses).

3 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exercice 14 :

Réaliser une fonction combienNonPresents qui reçoit en paramètre une liste V d’entiers et renvoie combien
d’entiers entre 0 et 99 (inclus) qui ne sont pas présents dans la liste V

Exercice 15 :
Ecrire une fonction Recherche(L,x) qui étant donnés une liste L et un objet x renvoie True si x est un élément de
la liste et False sinon

EXERCICE 16:
Ecrire une fonction récursive Recherche(L,x) qui prend en paramètre une liste de nombres L et un nombre x et
qui permet de tester l’existence de x dans la liste

Exercice 17 :Tri_selection
Écrire une fonction Tri_selection qui prend en argument une liste d’entiers L et permet de trier les éléments de
la liste L en ordre croissant en utilisant l’algorithme de tri par sélection :
 Trouver le plus petit élément et le mettre au début de la liste
 Trouver le 2e plus petit et le mettre en seconde position
 Trouver le 3e plus petit élément et le mettre à la 3e place,
 ...
Rq :Ne pas utiliser une autre liste intermédiaire

EXERCICE 18 : Palindrome :
Un palindrome est un mot dont l’ordre des lettres reste le même si on le lit de gauche à droite ou de droite à
gauche.
Par exemple, « ressasser »
Ecrire une fonction Palindrome qui prend en paramètre une chaîne de caractères et qui retourne True si la
chaîne est un palindrome et False sinon.

Exercice 19 :
Écrire une fonction récursive palindrome_rec(mot) qui prend comme argument une chaîne de caractères mot
et retourne True si cette chaîne est un palindrome, False sinon

EXERCICE 20 :
Ecrire une fonction SupprimeMaj qui prend en paramètre une chaîne de caractères s et qui supprime les
caractères majuscules de la chaîne
Par exemple :
 s=’’ Mon Cpge !’’
 L’appel de la fonction SupprimeMaj (s) retourne la chaîne ’’ on pge !’’

Exercice 21:

Écrire une fonction somme_matrices qui prend en paramètre deux matrices A et B de mêmes dimensions et
qui retourne la somme de A et de B

4 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exercice 22:

Ecrire la fonction transpose(M) qui prend en paramètre une matrice M et qui retourne la transposée de la
matrice M.

Exercice 23: nombre de chiffres d’un entier

On rappelle que le quotient de la division euclidienne d’un entier n par 10 donne le nombre de dizaines de cet
entier. Le quotient de la division euclidienne de n=5478 par 10 est par exemple 547.

En déduire une fonction NbChiffres(n) prenant en paramètre un entier naturel n (écrit en décimal) et
retournant le nombre de chiffres de cet entier n en base 10. Cette fonction sera définie récursivement, en
langage python.

Exercice 24:

Écrire une fonction récursive binaire(n) qui calcule la décomposition binaire de tout nombre entier n et renvoie
le résultat sous forme de liste de 0 et de 1
Exemple : L’appel de la fonction binaire(13) retourne la liste [1,1,0,1]

Exercice 25:

Ecrire la fonction copier3(NomFichier1, NomFichier2) qui prend en paramètre les noms de deux fichiers et
permet de copier le contenu du fichier NomFichier1 dans NomFichier2 en transformant chaque caractère en
majuscule

Exercice 26:

1. Définissez la classe point dont les caractéristiques sont :


 les coordonnés cartésiennes x et y ( dont x est l'abscisse et y est l'ordonnée )
 Les méthodes sont :
 __init__( self, absc, ord) qui permet de créer une instance de classe point
 Get_abscisse(self) qui retourne la valeur de x
 Get_ordonne(self) qui retourne la valeur de y
 Distance(self, autre) qui calcule la distance entre le point actuel et le point autre et
retourne le résultat

5 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 1 : Les algorithmes de tri


I. Le problème du tri :

Un algorithme de tri est un algorithme qui résout un problème de tri :


 Entrée : une séquence (liste) de n objets (a0,a1, · · · ,an−2,an-1). Ces objets peuvent être des
entiers, des chaînes de caractères . . . mais il faut qu’on puisse les ordonner par une relation
d’ordre
 Sortie : un réarrangement (a’0,a’1, · · · ,a’n−2,a’n-1) de la séquence d’entrée telle que :
a’0 ≤ a’1 ≤ · · · ≤ a’n−2 ≤ a’n-1 . Ce réarrangement peut être effectué sur place par modification
du même conteneur (liste) de la séquence initiale ou par création d’un nouveau conteneur
pour la séquence ordonnée.

II. Importance en informatique :

Le tri est historiquement un problème majeur en informatique pour plusieurs raisons :


 on a souvent besoin de trier des données (notes, noms, photos . . . )
 les algorithmes de tri sont des sous-programmes indispensables à de nombreuses
applications (gestionnaires de fenêtres graphiques ...) ou programmes (compilateurs)
 la diversité des algorithmes de tri qui ont été développés, présente un intérêt pédagogique
dans l’apprentissage de l’algorithmique

 Dans ce chapitre, pour simplifier, on se cantonnera au tri de listes de nombres.

III. Le tri par sélection :

III-1. Algorithme :
Le principe du tri par sélection d'une liste L = [L[0], L[1]….., L[len(L)-1]]:
 Pour chaque entier i (0 ≤ i ≤ len(L)-2) :
 parcourir les éléments L[i ], L[i + 1], . . ., L[len(L)-1]], retenir l'indice k du plus petit.
 placer au rang i le plus petit élément d’indice k (en échangeant L[i] et L[k]).
Exemple :

6 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

III-2. Code Python

def tri_selection( L ):
for i in range(len(L)-1):
k=i
for j in range(i+1,len(L)):
if L[j]<L[k]:
k=j
L[i],L[k]=L[k],L[i]

III-3. Temps d’exécution :

Pour tester le temps d’exécution, on a utilisé un PC Core 2 duo 2 Ghz - 2 Go de RAM avec Python 3.2.
Les nombres à trier sont des entiers aléatoires compris entre -100 et 100. Tous les temps donnés
sont en secondes :

Taille de la liste Temps d’exécution


N=0 0.0
N=5000 1.7009999752044678
N=10000 7.036999940872192
N=15000 15.96999979019165
N=20000 27.799999952316284
N=25000 43.67999982833862
N=30000 60.85599994659424

IV. Le tri par Bulle ( ou par échange) :

IV-1. Algorithme :

La technique d’échange consiste à comparer les éléments de la liste, 2 par 2, et à les permuter (ou
échanger) s’ils ne sont pas dans le bon ordre, jusqu’à ce que la liste soit complètement triée.
Le tri Bulle effectue des comparaisons entre voisins.
 À la première étape, L[0] et L[1] sont comparés et éventuellement permutés.
Ensuite, l’algorithme compare L[1] et L[2], et ainsi de suite jusque L[n-2] et L[n-1].
Etant parti de L[0] jusqu’à L[n-2], on peut voir qu’après cette première étape, L[n-1]
contiendra le maximum des valeurs de L, la sous-liste de L d’indices 0..(n-2) contenant les
autres valeurs déjà légèrement réorganisées.
 À la 2ème étape, on recommence donc les comparaisons/échanges pour les valeurs entre
L[0] et L[n-2], ce qui aura pour effet de mettre en place dans L[n-2], le second maximum et
de réorganiser à nouveau légèrement les autres valeurs dans la sous-liste de L d’indices
0..(n-3).
 À la ième étape, on devra donc réorganiser la sous-liste de L d’indices 0..(n-i)

7 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple :

IV-2. Code Python

def tri_bulle( L ):
n = len(L)
for j in range(n-1,0,-1):
for i in range(j):
if L[i] > L[i+1]:
L[i],L[i+1]=L[i+1],L[i]

IV-3. Temps d’exécution :

Pour tester le temps d’exécution, on a utilisé un PC Core 2 duo 2 Ghz - 2 Go de RAM avec Python 3.2.
Les nombres à trier sont des entiers aléatoires compris entre -100 et 100. Tous les temps donnés
sont en secondes :

Taille de la liste Temps d’exécution


N=0 0.0
N=5000 2.43399977684021
N=10000 8.674000024795532
N=15000 19.796000003814697
N=20000 35.66200017929077
N=25000 55.33300018310547
N=30000 79.20099997520447

V. Le tri par insertion:

V-1. Algorithme :

La technique consiste à considérer chaque élément à trier, un par un et à l’insérer en bonne place
relative dans la partie des éléments déjà triés aux étapes précédentes.
À chaque étape, l’insertion d’un élément est effectuée.
 Au départ, L[0] est l’élément de référence.
 À l’étape 1, l’élément L[1] est placé correctement par rapport à la partie déjà triée L[ :1],
c’est-à-dire uniquement L[0].
 À la ième étape, L[i] est donc inséré dans la sous liste L[ :i].

Exemple :

8 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

V-2. Code Python

def tri_insertion( L ):
n = len(L)
for i in range( 1,n):
x=L[i]
for j in range(i):
if L[j] > x:
L[i:i+1]=[]
L[j:j]=[x]
break

V-3. Temps d’exécution :

Pour tester le temps d’exécution, on a utilisé un PC Core 2 duo 2 Ghz - 2 Go de RAM avec Python 3.2.
Les nombres à trier sont des entiers aléatoires compris entre -100 et 100. Tous les temps donnés
sont en secondes :
Taille de la liste Temps d’exécution
N=0 0.0
N=5000 1.373000144958496
N=10000 5.241999864578247
N=15000 11.871999979019165
N=20000 20.918999910354614
N=25000 33.305999994277954
N=30000 46.76900005340576

VI. Les Tris récursives :

Pourquoi un autre algorithme de tri ? Parce que les algorithmes de tri par sélection, par insertion
ou par bulles sont lents lorsque le nombre de données à trier est grand.
 L’algorithme de tri rapide ou par fusion, est beaucoup plus rapide pour les listes de grande taille.
L’algorithme de tri rapide ou par fusion se programme naturellement de façon récursive
 L’algorithme de tri rapide ou par fusion est basé sur le principe diviser pour régner.

Diviser Pour Régner :


Diviser pour régner (divide and conquer) est une technique algorithmique consistant à
abandonner par itération ou récursivité une branche du traitement afin de diminuer l'effort à faire
pour obtenir la solution à un problème.
Un exemple simple est la recherche dichotomique, qui consiste à diviser un ensemble de
données ordonnés en deux, dont l'un des sous ensembles est abandonné au profit de l'autre.

9 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

VI-1. Le tri par fusion ( Merge Sort ) :

a. Algorithme :

 Partant d’une liste d’éléments à trier, on commence par diviser cette liste en deux sous-
listes (presque de même taille)
 on tri les deux sous listes
 puis on fusionne les sous listes triées.
 Une liste à un élément est triviale à trier et forme la condition d’arrêt de la procédure
récursive.

Exemple :

b. Code Python

 Version itérative pour la fonction Fusion


def fusion(L1,L2) :
L=[]
i,j=0,0
while i<len(L1) and j<len(L2):
if L1[i]<L2[j]:
L+=[L1[i]]
i=i+1
else:
L+=[L2[j]]
j=j+1
return L+L1[i : ]+L2[j : ]

def tri_fusion(L):
if len(L) <=1: return L
return fusion(tri_fusion(L[:len(L)//2]),tri_fusion(L[len(L)//2:]))

10 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 Version récursive pour la fonction Fusion

def fusion(L1,L2) :
if L1==[] :return L2
if L2==[] :return L1
if L1[0]<L2[0] :
return [L1[0]]+fusion(L1[1 :],L2)
else :
return [L2[0]]+fusion(L1,L2[1 :])

def tri_fusion(L):
if len(L)==1: return L
return fusion(tri_fusion(L[:len(L)//2]),tri_fusion(L[len(L)//2:]))

c. Temps d’exécution :

Pour tester le temps d’exécution, on a utilisé un PC Core 2 duo 2 Ghz - 2 Go de RAM avec Python 3.2.
Les nombres à trier sont des entiers aléatoires compris entre -100 et 100. Tous les temps donnés
sont en secondes :

Taille de la liste Temps d’exécution


N=0 0.0
N=5000 0.07800006866455078
N=10000 0.14100003242492676
N=15000 0.23399996757507324
N=20000 0.312000036239624
N=25000 0.40599989891052246
N=30000 0.49900007247924805

VI-2. Le tri rapide (Quicksort):

d. Algorithme :
La méthode consiste à placer un élément de la liste (appelé pivot) à sa place définitive, en
permutant tous les éléments de telle sorte que tous ceux qui sont inférieurs au pivot soient à sa
gauche et que tous ceux qui sont supérieurs au pivot soient à sa droite.
Cette opération s'appelle le partitionnement.
Pour chacune des sous-listes, on définit un nouveau pivot et on répète l'opération de
partitionnement. Ce processus est répété récursivement, jusqu'à ce que l'ensemble des éléments
soit trié.
Concrètement, pour partitionner une sous-liste :
 Choisir un élément du tableau appelé pivot ( premier , le dernier ou aléatoire).
 Ordonner les éléments du tableau par rapport au pivot.
 Appeler récursivement le tri sur les sous-tableaux à gauche et à droite du pivot.

11 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple :

e. Code Python

def tri_rapide(L):
if len(L)<=1: return L
Linf=[]
Lsup=[]
Lpivot=[]
p=L[0] #le choix du pivot
for i in range(len(L)):
if L[i]>p:
Lsup+=[L[i]]
elif L[i]<p:
Linf+=[L[i]]
else:
Lpivot+=[L[i]]
return tri_rapide(Linf)+Lpivot+tri_rapide(Lsup)

f. Temps d’exécution :

Pour tester le temps d’exécution, on a utilisé un PC Core 2 duo 2 Ghz - 2 Go de RAM avec Python 3.2.
Les nombres à trier sont des entiers aléatoires compris entre -100 et 100. Tous les temps donnés
sont en secondes :

Taille de la liste Temps d’exécution


N=0 0.0
N=5000 0.016000032424926758
N=10000 0.04699993133544922
N=15000 0.06299996376037598
N=20000 0.09299993515014648
N=25000 0.12400007247924805
N=30000 0.1400001049041748

12 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

VII. Comparaison entre les tris :

Taille Temps d’exécution


Sélection Bulle Insertion Fusion Rapide
N=0 0.0 0.0 0.0 0.0 0.0
N=5000 1.7009999752044678 2.43399977684021 1.373000144958496 0.07800006866455078 0.016000032424926758
N=10000 7.036999940872192 8.674000024795532 5.241999864578247 0.14100003242492676 0.04699993133544922
N=15000 15.96999979019165 19.796000003814697 11.871999979019165 0.23399996757507324 0.06299996376037598
N=20000 27.799999952316284 35.66200017929077 20.918999910354614 0.312000036239624 0.09299993515014648
N=25000 43.67999982833862 55.33300018310547 33.305999994277954 0.40599989891052246 0.12400007247924805
N=30000 60.85599994659424 79.20099997520447 46.76900005340576 0.49900007247924805 0.1400001049041748

13 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 2 : Les algorithmes de tri

Tri par Sélection – Tri par Bulle – Tri par insertion - Tri rapide (Quicksort) – Tri par fusion(Merge Sort)

Exercice :

1. Ecrire la fonction tri_selection( L)


2. Ecrire la fonction tri_bulle( L )
3. Ecrire la fonction tri_insertion( L )
4. Ecrire la fonction tri_fusion(L)
5. Ecrire la fonction tri_rapide(L)
6. Ecrire la fonction CreerListe(n) qui prend en paramètre un entier n et qui retourne une liste L de n
éléments remplié avec des valeurs aléatoires
Rq :
 Utiliser la fonction randint() du module random
 randint(a,b) : permet de générer un entier aléatoire compris entre [a et b],
Exemple d’utilisation :
from random import randint
X= randint(5, 18) #affecte à X un entier compris entre [5 et 18].

7. Ecrire la fonction temps(f,L) qui prend en paramètre une fonction de tri f


(Tri_sel,Tri_Bulle,Tri_insertion, …) et une liste L et qui retourne le temps d’exécution de l’algorithme
de tri sur la liste L
Rq :
 Utiliser la fonction time() du module time
 time() : permet de retourner le temps actuel en secondes
Exemple d’utilisation :
from time import time
t1=time()
tri_Bulle(L)
t2=time()

8. Ecrire un script qui permet de :


 Demande à l’utilisateur la taille de la liste
 Créer une L de n éléments remplié avec des valeurs aléatoires
 Affiche le temps d’exécution pour chaque type de tri

14 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 2 : complexité algorithmique

I. Introduction :

Il existe souvent plusieurs façons de programmer un algorithme. Si le nombre d’opérations à


effectuer est peu important et les données d’entrée de l’algorithme sont de faibles tailles, le choix de
la solution importe peu. En revanche, lorsque le nombre d’opérations et la taille des données
d’entrée deviennent importants, deux paramètres deviennent déterminants : le temps d’exécution
et l’occupation mémoire.
On n’exige donc pas seulement d’un algorithme qu’il résolve un problème, on veut également qu’il
soit efficace, c’est-à-dire :
• rapide (en termes de temps d’exécution),
• peu gourmand en ressources (espace de stockage, mémoire utilisée).

On a alors besoin d’outils qui nous permettront d’évaluer la qualité théorique des
algorithmes proposés. Le coût de la mémoire étant aujourd’hui relativement faible, on cherche en
général à améliorer la complexité en temps plutôt que la complexité en mémoire. Pour cette raison,
on s’intéressera donc au temps d’exécution.

II. Notion de complexité

II-1. Définition:

• La complexité d’un algorithme en temps : donne le nombre d’opérations effectuées lors de


l’exécution d’un programme.
On appelle Ci le coût en temps d’une opération i.
• La complexité en mémoire : donne le nombre d’emplacements mémoires occupés lors de
l’exécution d’un programme.

II-2. Intérêt de la complexité :

La complexité permet de :
• classer les problèmes selon leur difficulté,
• classer les algorithmes selon leur efficacité,
• comparer les algorithmes correspondant à un problème donné sans avoir à les implémenter,
c’est-à dire à les traduire dans un langage particulier.

II-3. Complexité dans les différents cas :

On distingue la complexité dans le pire des cas, la complexité dans le meilleur des cas, et la
complexité en moyenne. En effet, pour un même algorithme, suivant les données à manipuler, le
résultat sera déterminé plus ou moins rapidement.

• La complexité au meilleur : est le plus petit nombre d’opérations qu’aura à exécuter


l’algorithme sur un jeu de données de taille fixée. C’est une borne inférieure de la complexité
de l’algorithme sur un jeu de données de taille n.

15 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

• La complexité au pire : est le plus grand nombre d’opérations qu’aura à exécuter


l’algorithme sur un jeu de données de taille fixée. Comme il s’agit d’un maximum,
l’algorithme finira donc toujours avant d’avoir effectué ce nombre maximum d’opérations.
Cette complexité peut cependant ne pas refléter le comportement " usuel " de l’algorithme,
le pire cas ne pouvant se produire que rarement.

• La complexité en moyenne : est plus difficile à calculer. Il ne s’agit pas comme on pourrait le
penser de la moyenne des complexités au mieux et au pire. Concrètement, on se donne la
probabilité d’apparition de chacun des jeux de données.
Cette complexité en moyenne reflète le comportement " général " de l’algorithme si les cas
extrêmes sont rares ou si la complexité varie peu en fonction des données.

 Généralement, on s’intéresse au cas le plus défavorable, à savoir, la complexité dans le pire des
cas.

II-4. La complexité asymptotique : Notation Grand-O :

La complexité asymptotique d’un algorithme décrit le comportement de celui-ci quand la taille n des
données du problème traité devient de plus en plus grande (tend ver l’infini), plutôt qu’une mesure
exacte du temps d’exécution.
La notation O(f) décrit le comportement asymptotique d’une fonction f, c’est à dire pour des grandes
valeurs.

II-5. Classes de complexités :

Les complexités d’algorithmes (dans le pire des cas, que l’on notera O) les plus courantes sont :

Complexité temps d’exécution Description


O(1) temps constant Le temps d'exécution ne dépend pas des données
traitées, ce qui est assez rare !
O(log(n)) logarithmique Réponse immédiate
exemple : recherche dichotomique

O(n) linéaire augmentation linéaire du temps d'exécution quand le


paramètre croit (si le n double, le temps double).
exemple : recherche séquentielle

O(n log(n)) quasi-linéaire augmentation un peu supérieure à O(n)


exemple : Tri par fusion

O(n2) quadratique algorithmes avec deux boucles imbriquées. : Exemple


: Tris standards (Sélection, Bulle, Insertion)
O(np) polynomiales ici, np est le terme de plus haut degré d'un polynôme
en n ; il n'est pas rare de voir des complexités en O(n3)
ou O(n4).
O(pn) exponentielle quand le paramètre double, le temps d'exécution est
élevé à la puissance p avec p > 1.

 Un algorithme logarithmique est considérablement plus efficace qu’un algorithme linéaire (lui-
même plus efficace qu’un algorithme quadratique ou pire exponentiel). Cette différence devient

16 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

fondamentale si la taille des données est importante : le résultat peut se compter en millisecondes
pour une méthode et en heures pour une autre !

Exemple :

Avec un ordinateur qui fait 109 instructions par seconde, on aurait les temps d’exécution :

III. Calcul de la complexité :

L’efficacité d’un algorithme ne se mesure pas en secondes, par exemple, car cela impliquerait
justement de les implémenter mais de plus, ces mesures ne seraient pas significatives car
dépendantes de la machine utilisée.
On utilise donc des unités de temps abstraites correspondant au nombre d’opérations effectuées.
Chaque opération (addition, multiplication, comparaison, incrémentation, affectation, ...) consomme
alors une unité de temps. Le nombre d’opérations est égal à la somme de toutes les opérations.

III-1. Règles de calcul du grand O

 Si le coût d’un algorithme est une valeur constante O(1)


Exemple :
C(algorithme)= 15 alors la complexité asymptotique est O(1)

 Si le coût d’un algorithme dépend de n : on prend le plus grand degré


Exemple :
C(algorithme)= 5n2 + 2n+13 alors la complexité asymptotique est O(n2)

a. Le coût des instructions élémentaires : Le coût d'une opération élémentaire = 1

17 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

On appelle opération de base, ou opération élémentaire, toute :


 Affectation : x=2
 Test de comparaison : ==; <; <=; > ; >=; ! =
 Opération de lecture (input) et d’écriture (print)
 Opération arithmétique : + ; - ; * ; / ; // ; ** ; %;

Exemple : Que vaut le coût de l'algorithme A


x=2 #instr1 C(instr1)=1
x=x*2 # instr2 C(instr2)=2
print(x) # instr3 C(instr3)=1

C(A)= C(instr1)+ C(instr2)+ C(instr3)=4 O(1)

b. Le coût de if :

if condition: # la condition est en c1


instruction_1 # en c2
else:
instruction_2 # en c3

 le if sera en max(c1+c2,c1+3)
 Cette règle peut être généralisée pour une instruction if ayant une ou des parties elif.

Exemple : Que vaut la complexité de cet algorithme :


if i%2==0 : #2
n=i//2 #2
else :
i=i+1 #4
n=i//2
La complexité de l’algorithme est de : O(1)

c. Le coût des boucles (for ou while):

Le temps d'une boucle est égal à la multiplication de nombre de répétition par la somme du coût de
chaque instruction xi du corps de la boucle ;

 Coût(boucle for) =∑ 𝐶 (𝑥𝑖)

 Coût (boucle while) =∑(𝐶(𝑐𝑜𝑚𝑝𝑎𝑟𝑎𝑖𝑠𝑜𝑛) + 𝐶(𝑥𝑖))

Exemple 1: Que vaut la complexité de cet algorithme :


for i in range(6): #l nombre de répétition = 6
print(i) #le coût est 1
La complexité de l’algorithme est de ∑𝟓𝟎 𝟏 =6 O(1)

Exemple 2: Que vaut la complexité de cet algorithme :


for i in range(n): #l nombre de répétition = n

18 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

print(i) #le coût est 1


La complexité de l’algorithme est de ∑𝒊=𝒏−𝟏
𝒊=𝟎 𝟏 =n O(n)

Exemple 3: Que vaut la complexité de cet algorithme :


for i in range(n): #l nombre de répétition = n
for j in range(n-3): #l nombre de répétition = n-3
print(i+j) #le coût est 2

La complexité de l’algorithme est de :


𝒋=𝒏−𝟒
∑𝒊=𝒏−𝟏
𝒊=𝟎 ∑𝒋=𝟎 𝟐 =∑𝒊=𝒏−𝟏
𝒊=𝟎 𝟐(𝒏 − 𝟑)= 2n*(n-3)=2n2-6n O(n2)

d. L'appel d'une fonction :

Lorsqu'une fonction est appelée, le coût de cette fonction est le nombre total d'opérations
élémentaires engendrées par l'appel de cette fonction.

Exemple : Que vaut la complexité de cet algorithme :


def somme(n) :
s=0 #le coût est 1
for i in range(n+1) : #le nombre de répétition = n+1
s+=I #le coût est 2
return s #le coût est 1

y=0 #le coût est 1


for i in range(n): #le nombre de répétition = n
y+= somme(i) #le coût est 2+ coût (somme(i))=2+(2i+4)
print(y) #le coût est 1

La complexité de la fonction somme est de : 1+( ∑𝒊=𝒏


𝒊=𝟎 𝟐)+1=1+2(n+1)+1=2n+4 O(n)
La complexité de l’algorithme est :1+( ∑𝒊=𝒏−𝟏
𝒊=𝟎 (𝟐𝒊 + 𝟔) )+1 O(n2)

e. L'appel d'une fonction récursive:

Pour les fonctions récursives : le temps de calcul est exprimé comme une relation de récurrence (on
compte le nombre d'appels récursifs).

Exemple 1: Déterminez la complexité de la fonction récursive suivante


def factoriel(n) :
if (n == 0) : return 1
else : return n*factoriel(n-1)

Analyse de la complexité : C(n)=C(n-1)+1 avec C(0)=1

 Pour les problèmes de type :Diviser pour régner on applique le théorème Master theorem
suivant :

19 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Théorème : Master theorem

On considère un problème de taille n, qu’on découpe en a sous-problèmes de taille n/b permettant


de résoudre le problème. Le coût de l’algorithme est alors :
C(1) = 1
C(n) = a ×C(n/b) + f(n)
Avec f(n)= Reconstruction(n)= c×nα en general
Et a≥1 et b>1

soit k=logb a alors on distingue alors plusieurs cas :

 Cas1 : Si O(f(n))= O(nk), alors C(n) = O(nk log(n) ).

 Cas2 : Si O(f(n))= O(nk-e) pour une constante e>0, alors C(n) = O(nk).

 Cas3 : Si O(f(n))=O( nk+e ) pour une constante e>0, et si af(n/b) < cf(n) pour une constante c<1
alors C(n) = O(f(n))

Exemple :

C(n)=4C(n/2)+n alors :
 f(n)=n
 k= log24=2
 O(f(n))=O(n1)=O(nk-1)
Donc la complexité : O(n2)

20 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 3 : Complexité algorithmique

- - Initiation - -

Exercice 1: Donner la complexité des scripts suivants:

Script Python Complexité


a=2
b=2*a
print(b)
a=2
if a%2==0:
print(a,”estr un nombre pair”)
els :
a=a+1
print(a, ”maintenant est un nombre pair ”)
S=0
for i in range(5):
S+=3
s=0
x=0
for i in range(5):
if s%2==0:
s+=1
else:
x+=i
s+=i
print(s)

Exercice 2: Donner la complexité des scripts suivants:

Script Python Complexité


S=0
for i in range(n):
S+=3
S=0
for i in range(n):
for j in range(n-3):
S+=3
S=0
for i in range(n):
for j in range(i+1):
S+=3
S=0
for i in range(n):
for j in range(i,n):
S+=3
S=0
for i in range(n-1,-1,-1):
for j in range(i):
S+=3
S=0
for i in range(n):
for j in range(n):

21 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

for k in range(n):
S+=3
S=0
for i in range(n):
for j in range(i+1):
for k in range(j+1):
S+=3
i=1
s=0
while i <= n :
s=s+i
i=i+1

Exercice 3: Calculer la complexité pour ce script :

def somme(n) :
s=0
for i in range(n+1) :
s+=I
return s
y=0
for i in range(n):
y+= somme(i)
print(y)

Exercice 4: Donner la complexité dans le pire et le meilleur des cas de la fonction suivante :

def somme(a,b,n):
if a>b:
s=0
for i in range(n):
s=s+a
return s
else:
return b

Exercice 5: Donner la complexité dans le pire et le meilleur des cas de la fonction suivante :

def RechercheListe(L,x):
for i in L :
if i == x:
return True
return False
Exercice 6: Donner la complexité dans le pire et le meilleur des cas de la fonction suivante :

def RechercheMatrice (M,x):


n= len(M)
for i in range(n):
for j in range(n):
if M[i][j] == x :
return True
return False

22 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 4 : Complexité algorithmique (suite)

Exercice 7: Donner la complexité dans le pire et le meilleur des cas de la fonction suivante :

def Somme (M):


n= len(M)
s=0
for i in range(n):
for j in range(n):
s+=M[i][j]
return s
Exercice 8: Donner la complexité dans le pire et le meilleur des cas de la fonction suivante :

def Triangulaire (M):


n= len(M)
for i in range(n):
for j in range(i+1):
print(M[i][j])
Exercice 9:

1. Ecrire une fonction sansDoublons(t) qui retourne True si le tableau d'entiers t est sans doublons (c'est
à dire sans apparition multiple d'un élément), False sinon.
Exemples :

>>> a = [1,4,3]
>>> b = [1,0,0]
>>> sansDoublons(a) : True
>>> sansDoublons(b) : False
2. Donner et justifier la complexité dans le pire et le meilleur des cas de cette fonction.

Exercice 10:
1. Ecrire la fonction Produit(A,B) qui permet de retourner le produit matriciel de deux matrices carrées A
et B.
2. Donner la complexité dans le pire et le meilleur des cas de la fonction

Exercice 11: Donner la complexité pour chaque Tri :


Tri Complexité
def tri_selection( L ):
for i in range(len(L)-1):
k=i
for j in range(i+1,len(L)):
if L[j]<L[k]:
k=j
L[i],L[k]=L[k],L[i]
def tri_bulle( L ):
n = len(L)
for j in range(n-1,0,-1):
for i in range(j):
if L[i] > L[i+1]:
L[i],L[i+1]=L[i+1],L[i]

23 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n°5 : Complexité algorithmique (suite)

Exercice 12: Donner la complexité de la fonction récursive suivante :

def factoriel(n) :
if (n == 0) : return 1
else : return n*factoriel(n-1)
Exercice 13: Donner la complexité de la fonction récursive suivante :

def RD(L,x,inf,sup) :
if sup<inf:
return len(L)
else:
m=(inf+sup)//2
if L[m] ==x:
return m
if L[m] < x:
return RD(L,x,m+1,sup)
if L[m] > x:
return RD(L,x,inf,m-1)

Exercice 14: Donner la complexité pour chaque fonction récursive suivante

Formule de récurrence de la fonction Complexité

C(n)=4C(n/2)+n

C(n)=2C(n/2)+n

C(n) = 3C(n/4) + n

Exercice 15: Donner la complexité de ce Tri :


Tri Complexité
def fusion(L1,L2) :
if L1==[] :return L2
if L2==[] :return L1
if L1[0]<L2[0] :
return [L1[0]]+fusion(L1[1 :],L2)
else :
return [L2[0]]+fusion(L1,L2[1 :])
def tri_fusion(L):
if len(L) <=1: return L
return fusion(tri_fusion(L[:len(L)//2]),tri_fusion(L[len(L)//2:]))

24 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n°6 : Complexité algorithmique (suite)

Exercice 1 :

Un tableau X est trié par ordre croissant si x[i] <= x[i+1] pour tout i

1) Ecrire une fonction itérative Tab_Ord(X) qui prend en paramètre un tableau X et qui retourne True si
le tableau est trié en ordre croissant et False sinon.
2) Estimer sa complexité
3) Ecrire la version récursive de la question (1)
4) Estimer sa complexité

Exercice 2 : Médian d’une liste de nombres (Extrait CNC 2019 MP)

1) Écrire la fonction grands(L,x) qui reçoit en paramètres une liste de nombres L, et un élément x de L. La
fonction renvoie le nombre d’éléments de L qui sont supérieurs strictement à x.
2) Déterminer la complexité de la fonction grands (L, x), et justifier votre réponse.
3) Écrire la fonction petits(L,x) qui reçoit en paramètres une liste de nombres L, et un élément x de L. La
fonction renvoie le nombre d’éléments de L qui sont inférieurs strictement à x.

L est une liste de taille n qui contient des nombres, et m un élément de L. L’élément m est un médian de L, si
les deux conditions suivantes sont vérifiées :
• Le nombre d’éléments de L, qui sont supérieurs strictement à m, est inférieur ou égale à n/2
• Le nombre d’éléments de L, qui sont inférieurs strictement à m, est inférieur ou égale à n/2
Exemple : On considère la liste L = [ 25 , 12 , 6 , 17, 3 , 10 , 20 , 12 , 15 , 38 ], de taille n=10.
L’élément 12 est un médian de L, car :
• 3 éléments de L sont supérieurs strictement à 12, et 3 ≤ n/2 ;
• 5 éléments de L sont inférieurs strictement à 12, et 5 ≤ n/2.

4) Écrire la fonction median(L) qui reçoit en paramètre une liste de nombres L non vide, et qui renvoie un
élément médian de la liste L.
5) Déterminer la complexité de la fonction median(L), et justifier votre réponse.

Exercice 3 :

Pour convertir un nombre entier positif N de la base décimale à la base binaire, il faut opérer par des divisions
successives du nombre N par 2. Les restes des divisions constituent la représentation binaire.

1) Ecrire une fonction récursive « Binaire » permettant d’imprimer à l’écran la représentation binaire
d’un nombre N
2) Donner une formule récurrente exprimant sa complexité en nombre de divisions. Estimer cette
complexité

25 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exercice 4 : (Extrait CNC 2019 PSI)

1) Écrire la fonction factoriel(k) qui reçoit en paramètre un entier positif k et qui renvoie la valeur du
factoriel de k : k! = 1 * 2 * 3 * … * k.

Exemples :
• La fonction factoriel (5) renvoie le nombre : 120 = 1 * 2 * 3 * 4 * 5
• La fonction factoriel (0) renvoie le nombre : 1

2) Déterminer la complexité de la fonction factoriel (k), et justifier votre réponse


3) Écrire la fonction som_fact(L) qui reçoit en paramètre une liste L de nombres entiers positifs. La
fonction renvoie la somme des factoriels des éléments de L.
Exemple :
L = [ 5, 3, 0, 6, 1 ]
La fonction som_fact (L) renvoie la valeur de la somme : 5! + 3! + 0! + 6! + 1!
4) Déterminer la complexité de la fonction som_fact (L), et justifier votre réponse.

Exercice 5 :

Etant donné un tableau X composé de N éléments entiers. On voudrait déterminer son maximum par un
programme récursif basé sur le paradigme« diviser pour régner » :

1) En considérant que le maximum est le plus grand entre le dernier terme et le maximum des (n-1)
premiers termes.

 Ecrire la fonction Max(X)


 Estimer sa complexité.

2) En considérant que le maximum est le plus grand entre les maximums des deux moitiés du tableau.
Estimer sa complexité.

 Ecrire la fonction Max(X)


 Estimer sa complexité.

Exercice 6 : (Extrait CNC 2019 TSI)

1) Écrire la fonction somme (L) qui reçoit en paramètre une liste L de nombres entiers, et qui retourne la
somme des éléments de L.
Exemple :
La fonction somme ([ 7, 0 , -1, 5 , -3 ]) renvoie la valeur 8 = 7 + 0 + (-1) + 5 + (-3)
2) Déterminer la complexité de la fonction somme (L), et justifier votre réponse.
3) Écrire la fonction list_puissances (L, p) qui reçoit en paramètres une liste L de nombres entiers, et un
entier p strictement positif. La fonction renvoie une nouvelle liste qui contient les éléments de L
élevés chacun à la puissance p.
Exemple :
La fonction list_puissances ([ 7, 0 , -1, 5 , -3 ] , 2) renvoie la liste [ 49 , 0 , 1 , 25 , 9 ]
4) Écrire la fonction som_puiss (L, p) qui reçoit en paramètres une liste L de nombres entiers, et un
entier p strictement positif. La fonction renvoie la somme des éléments de L élevés chacun à la
puissance p.
Exemple :
La fonction som_puiss ([ 7, 0 , -1, 5 , -3 ], 2) renvoie le nombre 84 = 7² + 0² + (-1)² + 5² + (-3)²
5) Déterminer la complexité de la fonction som_puiss (L, p), et justifier votre réponse.

26 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Annexe : Complexité algorithmique

La notation O(•) :

 Les calculs à effectuer pour évaluer le temps d’exécution d’un algorithme peuvent parfois être longs et
pénibles ;
 De plus, le degré de précision qu’ils requièrent est souvent inutile ;
 On aura donc recours à une approximation de ce temps de calcul, représentée par la notation O(·)
 On définit symétriquement la minoration de f par g : f=Ω(g)
 On dit que f est du même ordre de grandeur que g et on écrit f = Ѳ ( g ) quand f = O ( g ) et g = O ( f )

Notation:
 Soit n la taille des données à traiter ; on dit qu’une function f(n) est en O(g (n)) (“en grand O de g (n)”)
si :
∃ n0 ∈ N, ∃ c ∈ R, ∀ n ≥ n0 : |f (n)| ≤ c|g (n)|
 Autrement dit : f (n) est en O(g (n)) s’il existe un seuil à partir duquel la fonction f (·) est toujours
dominée par la fonction g (·), à une constante multiplicative fixée près ;

Exemples d’utilisation de O(·)

 Prouvons que la fonction f2 (n) = 6n2 + 2n − 8 est en O(n2 ) :

 cherchons d’abord la constante c ; c = 6 ne peut pas marcher, essayons donc c = 7 ;


 on doit alors trouver un seuil n0 ∈ N à partir duquel : |6n2 + 2n − 8| ≤ 7|n2 | ∀ n ≥ n0 ;
 un simple calcul nous donne n1 = − 43 et n2 = 1 comme raciness de l’équation 6n 2 + 2n − 8 = 0 ;
 en conclusion, c = 7 et n0 = 1 nous donnent le résultat voulu ;

Simplifications:
On calcule le temps d’exécution comme avant, mais on effectue les simplifications suivantes :

 on oublie les constantes multiplicatives (elles valent 1) ;


 on annule les constantes additives ;
 on ne retient que les termes dominants ;

Exemple (simplifications):
Soit un algorithme effectuant g (n) = 4n3 − 5n2 + 2n + 3 opérations ; donc g (n) = O(n3 ).

27 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Annexe : Terminaison et correction d’un algorithme

1. Terminaison:

Pour montrer qu’un algorithme termine quel que soit le jeu de paramètres passé en entrée respectant la
spécification, il faut montrer que chaque bloc élémentaire décrit ci-dessus termine ! Or, les boucles for et les
instructions conditionnelles terminent forcément. Le seul souci pourrait venir d’une boucle while.

Variant de boucle:

Un variant de boucle est une quantité positive, à valeurs dans N, dépendant des variables de la boucle, qui
décroît strictement à chaque passage dans la boucle.
Exemple 1: la variant de la boucle est m
m=n
while m>0:
q=m//2
m=q

Exemple 2: la variant de la boucle est len(L)


s=0
while L!=[]: #Tant que L est non vide
s+=L[0]
L=L[1:] #L[1:] est la liste constituée de tous les éléments de L, sauf le premier.

2. Correction:

La notion essentielle pour montrer la correction des boucles est celle d’invariant de boucle

L’invariant de boucle:

Un invariant de boucle est une propriété dépendant des variables de l’algorithme, qui est vérifiée à chaque
passage dans la boucle.

 Correction des boucles while : inv= z.ym = xn


y=x
z=1
m=n
while m>0:
#Inv
q,r=m//2,m%2
if r==1:
z*=y
y*=y
m=q
#Inv

28 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 Correction des boucles for :

Exemple:

29 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Annexe : Complexité algorithmique

 List:

 Set:

 Dict:

30 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 3 : les arbres binaires

Les arbres sont très utilisés en informatique, d’une part parce


que les informations sont souvent hiérarchisées, et peuvent être
représentées naturellement sous une forme arborescente, et d’autre
part, parce que les structures de données arborescentes permettent
de stocker des données volumineuses de façon que leur accès soit
efficace.

I. Notions générales sur les arbres :

I-1. Définition :

Un arbre est un ensemble organisé de nœuds dans lequel chaque nœud a un père et un seul,
sauf un nœud que l’on appelle la racine.

Si le nœud p est le père du nœud f, nous dirons que f est un fils de p, et si le nœud p n’a pas
de fils nous dirons que c’est une feuille.

Chaque nœud porte une valeur(ou étiquette ou clé). On a l’habitude, lorsqu’on dessine un
arbre, de le représenter comme le schéma ci-dessous :

I-2. Arbre binaire :

Dans un arbre binaire, chaque nœud possède au plus deux nœuds fils au niveau inférieur,
habituellement appelés fils gauche et fils droit.
Exemple :
Arbre binaire d’un seul nœud Arbre binaire de 5 nœuds Arbre binaire de 7 nœuds

31 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

I-3. La terminologie de base sur les arbres :

 les descendants : d’un nœud p sont les nœuds qui apparaissent dans ses sous-arbres
 un ancêtre : d’un noeud p est soit son père, soit un ancêtre de son père,
 un frère : d’un noeud p est un fils du père de p, et qui n’est pas p.
 Taille d’un arbre : nombre de noeuds dans l’arbre
 le chemin : On appelle chemin du noeud p , la suite des nœuds par lesquels il faut passer
pour aller de la racine vers le noeud p :
Exemple :
Chemin du nœud(6) = (8,4,6)
Chemin du noeud (13) = (8,10,14,13)
 Niveau d'un nœud : Les nœuds d’un arbre se répartissent par niveaux : le premier niveau
(par convention ce sera le niveau 0) contient la racine seulement, le deuxième niveau
contient les deux fils de la racine,. . . , les noeuds du niveau k sont les fils des noeuds du
niveau k − 1,. . . .
 Profondeur d’un nœud : la profondeur d'un nœud p est égale au nombre de branches à
partir de la racine pour aller jusqu'au nœud p.
Exemple : Profondeur du nœud (13) = 3
 Hauteur d’un arbre : Distance maximum (nombre de branches) pour aller de la racine à une
des feuilles de l’arbre.
Exemple : Hauteur de l’arbre d l’exemple = 3

Attention, la définition de la hauteur varie en fonction des auteurs. Pour certains la hauteur
d’un arbre contenant un seul nœud est 1.

 Degré d'un nœud : Par définition le degré d'un nœud est égal au nombre de ses descendants
(enfants).
Dans l’arbre binaire : 0≤ le degré d’un nœud ≤ 2

 Arbre parfait : c'est un arbre binaire dont tous les nœuds de chaque niveau sont présents
sauf éventuellement au dernier niveau où il peut manquer des nœuds (nœuds terminaux =
feuilles), dans ce cas l'arbre parfait est un arbre binaire incomplet et les feuilles du dernier
niveau doivent être regroupées à partir de la gauche de l'arbre.

Exemple : arbre parfait complet

32 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple : arbre parfait incomplet

Exemple 1:arbre non parfait

Exemple 2:arbre non parfait

Rq : Un arbre binaire parfait se représente classiquement dans un tableau (une seule liste)

 Arbre équilibré : On dit qu'un arbre binaire A est équilibré si tous les chemins menant de la
racine à une feuille ont pour longueur Hauteur(A) ou Hauteur(A)-1

Exemple 1: arbre équilibré

33 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple 2: arbre équilibré

Exemple 3: arbre équilibré

II. Représentation d'un arbre en Python:

Il existe différentes manières de représenter un arbre binaire en Python. A l'aide :


 d'une liste de listes
 d’un tableau (une lise)

II-1. arbre sous forme d’une liste de listes :

Arbre=[étiquette,fils_Gauche, fils_Droit]

 fils_Gauche est un sous arbre : fils_Gauche =[étiquette, fils_Gauche, fils_Droit]


 fils_Droit est un sous arbre : fils_Gauche =[étiquette, fils_Gauche, fils_Droit]
 Arbre vide : arbre=[]
 Feuille =[ étiquette, [], []]

Exemple 1:

L’arbre suivant sera représenté en Python sous forme :


A=[10,[4, [ ], [ ]],[20,[ ],[ ] ]]

34 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple 2:

L’arbre suivant sera représenté en Python sous forme :


A=[ 1,[2,[4, [ ], [ ]],[5,[7, [ ], [ ]] ,[ 8, [ ], [ ] ]]],[3, [ ],[6,[9, [ ], [ ]], [ ]]]]

Parcours d’un arbre binaire :

On se balade autour de l’arbre en suivant les pointillés dans l’ordre des numéros indiqués :

A partir de ce contour, on définit trois parcours des sommets de l’arbre :


 l’ordre préfixe : on liste chaque sommet la première fois qu’on le rencontre dans la balade.
Ce qui donne ici : r,a,c,h,d,i,j,l,b,e,k, f
 l’ordre postfixe : on liste chaque sommet la dernière fois qu’on le rencontre. Ce qui donne ici
: h,c, i ,l, j ,d,a,k,e, f ,b, r
 l’ordre infixe : on liste chaque sommet ayant un fils gauche la seconde fois qu’on le voit et
chaque sommet sans fils gauche la première fois qu’on le voit. Ce qui donne ici :
c,h,a,i,d,l,j,r,k,e,b,f

35 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

II-2. arbre sous forme d’un tableau :

On peut convenir de stocker les étiquettes dans un tableau L, en numérotant les nœuds de haut en
bas et de gauche à droite pour chaque niveau, L[k] contenant l’étiquette du nœud n° k s’il existe,
sinon (valeur absente de l’ensemble des étiquettes possibles, par exemple :[])
Donc :
 La première case (indice 0) de la liste constitue la racine de l’arbre,
 Pour toute case portant l’indice i, son fils gauche sera situé à l’indice 2i+1et son fils droit à
l’indice 2i+2
 Une case avec la valeur [] signifie un arbre vide (l’absence de nœud).

Cette représentation est avantageuse dans le cas des arbres parfaits (on stocke les n nœuds dans
L[0], L[1],…,L[n-1]). Réciproquement on stocke n valeurs dans un arbre de hauteur ⌊log2n⌋

Voici quelques exemples :

Exemple 1:
En Python :

0 1 2 3 4
1 5 2 0 3

Exemple 2:
En Python :

0 1 2 3 4 5 6 7 8
‘e’ ‘i’ ‘f’ ‘b’ [] ‘a’ ‘d’ [] ‘c’

Toutefois elle a de gros défauts dans le cas général : dans le pire des cas, on peut avoir besoin d’un
tableau de taille 2n pour stocker n nœuds ! De plus, la structure récursive de l’arbre binaire
n’apparaît pas clairement

36 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 7 : arbres binaires

Exercices d’application

Exercice 1 : Avec Python, créer les arbres suivants :

Exercice 2 :
1. Ecrire la fonction Vide(A) qui prend en paramètre un arbre A et qui détermine si l’arbre est vide ou
non
2. Ecrire la fonction Racine(A) qui prend en paramètre un arbre A et qui retourne la valeur de la racine
3. Écrire une fonction booléenne Feuille(A) qui teste qu’un arbre est une feuille, c'est-à-dire un nœud qui
n'a aucun fils.
4. Ecrire la fonction NbrNoueds(A) qui prend en paramètre un arbre A et qui retourne le nombre de
nœuds de l’arbre
5. Ecrire la fonction SommeArbre(A) qui prend en paramètre un arbre A et qui retourne la somme de
valeurs de l’arbre
6. Ecrire la fonction booléenne Recherche(A,x) qui prend en paramètre un arbre A et qui teste si une
valeur x appartient à un arbre.
7. Ecrire la fonction Minimum(A) qui prend en paramètre un arbre A et qui retourne la valeur minimale
de l’arbre
8. Écrire la fonction Hauteur(A) qui calcule la hauteur d'un arbre, définie ainsi :
 la hauteur d'un arbre est 1 + le maximum des hauteurs des sous-arbres (gauche, droit),
 la hauteur d'une feuille étant 0.
9. Écrire une fonction booléenne ARB(A) qui teste qu'une liste représente bien un arbre binaire.
10. Écrire la fonction infixe (A) qui retourne la liste résultant du parcours infixe d’un arbre :
 en chaque noeud, on parcourt le fils gauche, puis on note la valeur du noeud, puis on
parcourt le fils droit.
11. Écrire la fonction prefixe (A) qui retourne la liste résultant du parcours préfixe d’un arbre :
 en chaque noeud, on note la valeur du noeud ,puis on parcourt le fils gauche, puis on
parcourt le fils droit.
12. Écrire la fonction postfixe (A) qui retourne la liste résultant du parcours postfixe d’un arbre :
 en chaque noeud, on parcourt le fils gauche, puis on parcourt le fils droit, puis on note la
valeur du noeud.

37 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 8 : arbres binaires (suite)

Exercice 1 :

1. Ecrire la fonction NbrFeuilles(A) qui prend en paramètre un arbre A et qui retourne le nombre de
feuilles de l’arbre A (ou nœuds externes).

2. Ecrire la fonction NbrNoeudInternes (A) qui prend en paramètre un arbre A et qui retourne le nombre
de nœuds internes de l’arbre A.

3. Ecrire la fonction AffichageLargeur(A) qui prend en paramètre un arbre A et qui affiche les élémént
de l’arbre en largeur
Exemple :

Pour l’arbre ci-dessus, la fonction affiche :7 4 16 1 6 3

Exercice 2 : Arbre binaire de recherche

Un arbre binaire A est un arbre binaire de recherche si, pour tout nœud s de A, les contenus des nœuds
du sous-arbre gauche de s sont strictement inférieurs au contenu de s, et que les contenus des nœuds
du sous-arbre droit de s sont strictement supérieurs au contenu de s.

1. Écrire une fonction ABR(A) qui vérifie si un arbre donné est bien un arbre binaire de recherche.

2. Écrire la fonction mem(A,x) qui prend en paramètre un ABR et un nombre x et qui recherche si x
appartient à A.

3. Écrire une fonction qui prend un arbre binaire de recherche et renvoie son minimum.

4. Écrire une fonction qui prend un arbre binaire de recherche et renvoie son maximum.

5. Écrire la fonction add(A,x) qui ajoute un élément donné x à un arbre binaire de recherche donné A
tout en garantissant que l’arbre reste un arbre binaire de recherche.

38 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 8 (suite): arbres binaires-Révision

Exercice 1:

Dans cet exercice, on cherche à stocker un ensemble de contacts téléphoniques dans un arbre binaire de
recherche.
Un contact téléphonique est composé d'un nom (représenté par une chaîne de
caractères) et d'un numéro de téléphone (représenté par un entier).

Un contact téléphonique sera représenté dans cet exercice par un dictionnaire


Exemple :
D={nom :’ bennani’,tel :’212623145623’}

Définition d’un arbre binaire de recherche :

• L'arbre contient deux types d'éléments : des nœuds (chacun contenant un contact et deux
sousarbres fils) et des feuilles (qui ne contiennent aucune information).
• Lorsqu'un nœud contient un contact ayant le numéro de téléphone n, tous les contacts ayant un
numéro de téléphone strictement inférieur à n se trouvent dans le sous-arbre gauche, et tous les
contacts ayant un numéro de téléphone strictement supérieur à n se trouvent dans le sous-arbre
droit
.
1) Écrivez une fonction listeContacts qui prend en paramètre un arbre et
qui retourne la liste des contacts de cet arbre, triée par ordre croissant des numéros de téléphone.

2) Écrivez une fonction rechercheContact qui prend en paramètre un arbre


et un numéro de téléphone, et qui retourne le nom du contact ayant ce numéro de téléphone, ou la
chaîne de caractères vide sinon. Votre fonction doit profiter des caractéristiques de l'arbre binaire de
recherche.

3) Écrivez une fonction MaxContact qui prend en paramètre un arbre


et qui retourne le contact qui le plus grand numéro de téléphone

4) Écrivez une fonction ajouteContact qui prend en paramètre un arbre et


un contact, et qui ajoute ce contact dans l'arbre. L'ajout doit se faire en conservant les propriétés de
l'arbre binaire de recherche.

39 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exercice 2:

1. Ecrire la fonction Croissant(A) qui prend en paramètre un arbre binaire de recherche A et qui retourne
une liste croissante des valeurs de l’arbre
Rq :Ne pas utiliser un algorithme de tri
Exemple :

L’appel de la fonction L= Croissant(A) retourne la liste suivante : L=[1,3,4,6,7,8,10,13,14]

2. Ecrire la fonction Complet(A) qui prend en paramètre un arbre binaire A et qui retourne un booléen
indiquant si A est un arbre binaire parfait complet ou non

Exemple :

L’appel de la fonction Complet(A1) retourne True et l’appel de la fonction Complet(A2) retourne False

Exercice 3:

On considère les expressions arithmétiques sur les entiers n’utilisant que les opérateurs +,- ,x, et ÷
Ces expressions peuvent être représentées par des arbres binaires dont les nœuds internes (nœuds non vides
qui ne sont pas des feuilles) sont étiquetés par l’un des quatre opérateurs ,tandis que les feuilles sont
étiquetées par des entiers.
Par exemple, l’arbre représenté sur la figure 1 représente l’expression arithmétique

40 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Remarque :
Les opérateurs sont représentés par la chaîne de caractères qui leur correspond. Par exemple, l’opérateur + est
représenté par ‘+’ :

1) écrivez la fonction valide(a) qui teste si un arbre binaire a ne contenant que des entiers et des
opérateurs, représente bien une expression arithmétique valide (chaque nœud étiqueté par un
opérateur doit avoir deux fils non vides et les entiers ne doivent apparaître que sur les feuilles de
l’arbre).

Indication : On peut vérifier que la condition est vraie pour la racine puis tester récursivement si les
sous-arbres droit et gauche sont également valides

2) Écrivez récursivement la fonction eval(a) qui renvoie la valeur correspondant à l’expression


arithmétique représentée par l’arbre a (par exemple, sur l’arbre illustré par la figure 1, la fonction
eval(a) doit renvoyer 12 ). On suppose ici que l’arbre représente une expression valide.

Indication : Si le nœud considéré contient un entier, l’évaluation en ce nœud doit renvoyer la valeur
de l’entier, si par contre le nœud contient par exemple un ‘+’ , l’évaluation doit renvoyer le résultat de
l’évaluation du fils gauche plus le résultat de l’évaluation du fils droit..

41 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 4 : Introduction à la théorie des graphes

I. Origines ?

Le problème des sept ponts de Königsberg Résolu par


Leonhard Euler en 1736 est à l’origine de la théorie
des graphes. Ce problème consiste à déterminer s'il
existe ou non une promenade dans les rues de
Königsberg permettant, à partir d'un point de départ
au choix, de passer une et une seule fois par chaque
pont, et de revenir à son point de départ, étant
entendu qu'on ne peut traverser le Pregel qu'en
passant sur les ponts.

II. Définitions :

 Graphe : Un graphe G est défini par G=(V,U), ou V est un ensemble de sommets et U


l’ensemble d'arcs(ou arêtes) ;
 Un arc (ou arête) : est un couple de sommets, donc, un élément du produit cartésien VxV
 Graphe orienté et Graphe non orienté : Si les arêtes ne sont pas orientées, on parle d’un
graphe non orienté. Dans le cas contraire on parle d’un graphe orienté et les arêtes sont
appelées aussi les arcs.
 Graphe Pondéré : Un graphe pondéré est défini par le triplet (V,U,C) où : V est l’ensemble
des sommets, U est l’ensemble des arrêtes (ou arcs), et C est la fonction de coût de U dans
IR. Par convention Cu représente le coût ou le poids de l’arc (ou de l’arête) u.
 Graphe Connexe : Un graphe connexe est un graphe dont tout couple de sommets peut être
relie par une chaine de longueur n>=1

III. Vocabulaire de la théorie des graphes :

 Ordre du Graphe : le nombre de sommet du Graphe


 Degré d’un sommet : nombre d’arêtes reliées à ce sommet
 Adjacences: Deux arcs sont dits adjacents s'ils ont une extrémité en commun. Et deux
sommets sont dits adjacents si un arc les relie.
 Boucle : est un arc qui part d’un sommet vers le même sommet
 Chaîne : Une chaine de longueur n est une suite de n arêtes qui relient un sommet i à un
autre j ou à lui même.
 Cycle : Un cycle est une chaine qui permet de partir d’un sommet et revenir à ce sommet en
parcourant une et une seule fois les autres sommets.
 Distance entre deux sommets i et j : est la longueur de la chaine la plus courte qui les relie
 Chemin : c’est une chaine bien orientée
 Circuit : est un cycle "bien orienté", à la fois cycle et chemin.
 Chaine eulérienne: une chaine est dite eulérienne est une chaine comportant exactement
une fois toutes les arêtes du graphe.
 Cycle eulérien : si le sommet de départ d’une chaine eulérienne et celui d’arrivé on parle de
cycle eulérienne
 Graphe eulérien : Un graphe admettant une chaine eulérienne est dit Graphe eulérien

42 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 Cycle hamiltonien : c’est un cycle passant une seule fois par tous les sommets d’un graphe et
revenant au sommet de départ.
 Un graphe simple : est un graphe sans boucle tel qu'entre deux sommets différents, il y ait
au plus un arc.
 Dans un graphe simple, on pourra donc noter un arc à l'aide de ses extrémités initiale
et finale.
 Dans un graphe simple, on peut parler de l'ensemble des arcs.

IV. Représentation informatique d’un graphe :

Un graphe peut être implémenté de différentes manières selon le langage utilisé. En Python on peut
représenter un graphe à l’aide d’un dictionnaire ou à l’aide d’une matrice d’adjacence.

Exemple :

Propriétés de la matrice d’adjacence :


 La matrice est symétrique si le graphe n’est pas orienté.
 La somme des nombres d’une même ligne (ou d’une même colonne) donne le degré du
sommet correspondant.
 La diagonale ne contient que des zéros.
 Les termes aij de la matrice An donnent le nombre de chaînes de longueur n reliant i à j.

V. PILE et FILE :

Les notions de pile et de file sont deux structures de données abstraites importantes en
informatique.
On limite ci-dessous la présentation de ces notions aux besoins des
parcours de graphes envisagés ci-après.
Pile: Structure LIFO (last in, first out)

La structure de pile est celle d’une pile d’assiettes :


 Pour ranger les assiettes, on les empile les unes sur les autres.
 Lorsqu’on veut utiliser une assiette, c’est l’assiette qui a été empilée en dernier qui est
utilisée.
FILE (queue): Structure FIFO (first in, first out).

43 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

La structure de file est celle d’une file d’attente à un guichet :


 Les nouvelles personnes qui arrivent se rangent à la fin de la file
d’attente.
 La personne servie est celle qui est arrivée en premier dans la file.

VI. Parcours de graphe :

Par la suite nous utilisons la représentation en utilisant la matrice d’adjacence d’un graphe

VI-1. Le parcours en profondeur d'abord DFS (Depht First Search)

Algorithme :
 Initialement tous les nœuds sont marqués " non visités".
 Choisir un nœud v de départ et le marquer " visité".
 Chaque nœud adjacent à v, non visité, est à son tour visité en utilisant DFS récursivement.
 Une fois tous les nœuds accessibles à partir de v ont été visités, la recherche de v ( DFS(v) )
est complète.
 Si certains nœuds du graphe restent "non visités", sélectionner un comme nouveau nœud
de départ et répéter le processus jusqu'à ce que tous les nœuds soient visités.

Exemple :
Soit le graphe suivant :

Le parcours en profondeur de ce graphe : A, B, C, F, D, H, I, G, E


En python :

On peut réaliser le parcours en profondeur en utilisant la récursivité ou en utilisant les Piles. Ci-après
les deux variantes :

44 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

parcoursProfondeur(g) : fonction qui lance le parcours, elle peut faire appel soit à la fonction
parcoursDFSpile soit à la fonction parcoursDFSRecursif selon le parcours souhaité
succNonVisite(g,s,test): retourne la liste des successeurs non visités de s

VI-2. Le parcours en largeur d'abord :BFS (Breadh First Search )

On procède par niveau en considérant d'abord tous les sommets à une distance donnée, avant de
traiter ceux du niveau suivant.

Exemple : Le parcours en largeur du graphe précèdent visite les sommets dans l’ordre suivant : A, B,
D, E, C, G, F, H, I

En python :

45 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 9 : graphe

Initiation

Rappel :

Dans les exercices suivants on suppose : qu'un graphe G d'ordre N est représenté par une matrice carrée de
dimension NxN, un sommet est représenter par un indice i ( tel que 0 <= i < N), et un arc qui relie deux
sommets a et b est représenter par le tuple (a, b)

Si G est un graphe non orienté, la valeur de la case G[a][b] est 1 (resp le cout de l'arête si le graphe est valué)
s'il y a un arc qui relie les deux sommet a et b ou 0 si non

Si G est un graphe orienté, la valeur de la case G[a][b] est 1 (resp le cout de la flèche si le graphe est valué) il y a
une flèche du sommet a vers le sommet b ou 0 si non

1) Définir la fonction def OrdreGraphe(G) qui prend comme argument un graphe G et retourne l'ordre du
graphe G

Exemple : si le graphe G est sous la forme :

la fonction OrderGraphe retourne la valeur 4

2) Définir la fonction def degre_sommet(G, s) qui prend comme argument un graphe G et un sommet s et
retourne le degré de sommet s
Exemple :
si le graphe G est sous la forme :

Et s=2 la fonction degre_sommet retourne la valeur 2

3) Définir la fonction def EstSommetAdjacent(G, x, y) qui prend comme argument un graphe G non orienté
et deux sommets x et y; et elle retourne True si x et y sont adjacents ou false si non

46 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple :
si le graphe G est sous la forme :

et si x=1 et y=3 la fonction EstSommetAdjacent retourne la valeur False

4) Définir la fonction def EstIsole( G, a) qui prend comme argument le graphe non orienté G et un sommet a
de G et qui renvoie True si a est un sommet isolé ou False si non
Exemple :
si le graphe G est sous la forme :

et si a=1 la fonction EstIsoleretourne la valeur False

5) Définir la fonction def ListeArc(G) qui prend comme argument un graphe G non orienté et retourne la
liste des arcs qui relie les sommets du graphe G
Exemple :
si le graphe G est sous la forme :

47 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 10 : graphe

Parcours :
Le parcours en largeur d'abord :BFS (Breadh First Search )
Le parcours en profondeur d'abord DFS (Depht First Search)

Le parcours :

1. Ecrire la fonction succ(g,s): retourne la liste des successeurs de s


2. Ecrire la fonction succNonVisite(g,s,test): retourne la liste des successeurs non visités de s
3. Ecrire la fonction parcoursProfondeur(g) qui affiche le graphe g en utilisant le parcours DFS :

Alorithme :

 Initialement tous les nœuds sont marqués " non visités".


 Choisir un nœud v de départ et le marquer " visité".
 Chaque nœud adjacent à v, non visité, est à son tour visité en utilisant DFS récursivement.
 Une fois tous les nœuds accessibles à partir de v ont été visités, la recherche de v ( DFS(v) ) est complète.
 Si certains nœuds du graphe restent "non visités", sélectionner un comme nouveau nœud de départ et répéter
le processus jusqu'à ce que tous les nœuds soient visités.
Exemple :
Soit le graphe suivant :

Le parcours en profondeur de ce graphe : A, B, C, F, D, H, I, G, E

4. Ecrire la fonction parcoursLargeur(g) qui affiche le graphe g en utilisant le parcours BFS :

Exemple :
Le parcours en largeur du graphe précèdent visite les sommets dans l’ordre suivant : A, B, D, E, C, G, F, H, I

48 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 11 : graphe

Plus court chemin : Algorithme de DIJKSTRA

Ecrire la fonction dijkstra(G,a,b) qui prend en paramètre un graphe G orienté pondéré et qui retourne le plus
court chemin entre deux sommets a,b en utilisant l’algorithme de DIJKSTRA

Algorithme de DIJKSTRA :

On se propose de déterminer sur le graphe pondéré ci-dessous le trajet de A à H de durée minimale.

Les étapes :

Etape 1 :

 Placer les sommets du graphe dans la première ligne d'un tableau.


 Sur la 2ème ligne du tableau, écrire le coefficient 0 sous le sommet de départ et le coefficient ∞ sous
les autres sommets.

Etape 2 :

 Sur la dernière ligne écrite, repérer le sommet X de coefficient minimal

49 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 Commencer une nouvelle ligne et rayer toutes les cases vides sous X.

Etape 3 :
 Pour chaque sommet Y adjacent à X, calculer P, la somme du coefficient de X et du poids de
l'arête reliant Y à X

Pour B , le calcul de P est le suivant :


le coefficient de A est 0, le poids de l'arête reliant B à A est 4 donc P = 0 + 4 =4

 Si P est strictement inférieur au coefficient de Y, inscrire Px dans la case correspondante de la


colonne Y.
 Sinon, recopier le coefficient de Y et compléter la ligne par les coefficients de la ligne
précédente.
Ici, le coefficient de B est ∞ , et P = 4.
4 est strictement inférieur à ∞ donc on inscrit 4A dans le tableau.

Pour I et J on procède de la même façon et on obtient :

50 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 S'il reste des sommets à sélectionner, on recommence à l'étape 2 (ici c'est le cas) sinon on passe à
l'étape 4.

Etape 4 :
 Lire la durée minimale sur la dernière ligne du tableau dans la colonne H, ici 13
 Lire le trajet de durée minimale "à l'envers" en commençant par la colonne H et en lisant les indices :

A - J - G - F – H Le trajet de durée minimale (13 min) est A - J - G - F - H

51 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Plus court chemin : Algorithme de DIJKSTRA

#-----------------------Algorithme de DIJKSTRA---------------------------
def DisMin(L,T):
m=float("inf")
for i in range(len(T)):
if (i not in L) and (T[i][0]<m):
m=T[i][0]
p=i
return p,m

#-------------------------------------------------------------------------

def VoisinsNonMarq(G,L,T,p):
L1=[j for j in range(len(G[0])) if j not in L and G[p][j]!=0]
distance=T[p][0]
for i in L1:
if (distance+G[p][i])<T[i][0]:
T[i][0]=(distance+G[p][i])
T[i][1]=p

#-------------------------------------------------------------------------

def Dijkstra(G,d,a):
T=[[float("inf"),None] for i in range(len(G))]
T[d][0]=0
L=[]
while a not in L:
p,m=DisMin(L,T)
L.append(p)
VoisinsNonMarq(G,L,T,p)
return m,T

#-------------------------------------------------------------------------

def chemin(T,d,a):
C=[a]
s=a
while d not in C:
s=T[s][1]
C=[s]+C
return C
#-------------------------------------------------------------------------
#------------------------------programme principal------------------------
G=[[0,0,5,0,0,35,0],[0,0,9,0,15,0,0],[0,0,0,0,10,8,0],[3,12,0,0,0,0,0],
[0,0,0,0,0,0,14],[0,0,0,0,0,0,13],[0,0,0,0,0,0,0,0]]
debut=3
fin=6
m,T=Dijkstra(G,3,6)
C=chemin(T,debut,fin)
print("Chemin est :",C)
print("Distance minimale est :",m)

52 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 5 : Algèbre relationnelle

I. Introduction :

I-1. Les requêtes :

Une requête est destinée à obtenir des informations précises et ordonnées sur la base de données.
On peut également par le biais des requêtes :
 effectuer des calculs,
 obtenir des statistiques,
 modifier les tables,
 créer de nouvelles tables
 gérer des utilisateurs…

Trois façons de créer des requêtes :

 L’algèbre relationnelle qui permet de préparer une requête en utilisant un langage


algébrique.
 Le QBE (Query By Exemple), qui est un mode graphique où l’on clique sur les éléments
choisis pour construire la requête. C’est un moyen interactif et puissant utilisé par Access.
 Le SQL (Structured Query Langage) qui est le langage des requêtes, qui est plus puisant que
le QBE et plus universel.

I-2. Définition de l’algèbre relationnelle :

Ensemble d’opérations permettant de manipuler des relations (schéma relationnel) et produisant


comme résultat de nouvelles relations.

I-3. Objectif de l’algèbre relationnelle :

Description algorithmique ou symbolique préliminaire à l’utilisation d’un langage non procédural de


type SQL.

II. Types d’opérations :

 Opérateurs unaires : Projection, Sélection.


 Opérateurs binaires ensemblistes : Union, Intersection, Différence.
 Opérateurs n-aires : Produit cartésien, Jointure, Division cartésienne :
 Fonctions d’agrégation : Min, Max, Somme, Moyenne :
.

53 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

III. Opérateurs unaires :

III-1. Projection: π

La projection permet d’extraire des données d’une table, en ne conservant que les colonnes
souhaitées.

Exemple :

On considère par exemple la relation CLIENT:

Sa projection sur les attributs (NumCli, Nom):


En langage algébrique : π NumCli, Nom (Client)

III-2. Sélection : σ

Permet d’extraire les lignes d’une table qui vérifient la réalisation d’une certaine condition (on parle
parfois de critère).

Exemple : On aimerait avoir les clients qui portent comme prénom : ‘’omar’’

En langage algébrique : σPrénom= ‘’omar’’(Client)

54 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

IV. Opérateurs binaires ensemblistes :

Dans ce qui suit on considère, deux relations livre1 et livre2 sur lesquelles on peut appliquer les
opérateurs ensemblistes.

IV-1. Union : ∪

L’union consiste à combiner deux relations (compatibles) pour créer une


troisième relation qui contient toutes les occurrences appartenant à l’une ou
à l’autre des relations de départ.

Notation :
 L’union de deux relations R1 et R2 est l’ensemble des tuples
comprises dans R1 ou dans R2.
 On la note R1 ∪ R2.

Exemple : Voici le résultat de l’union des deux relations livre1 et livre2 :

IV-2. L’intersection : ∩

L’intersection consiste à combiner deux relations (compatibles) pour créer


une troisième relation qui contient toutes les occurrences appartenant à
l’une et à l’autre des relations de départ.
Notation : R1 ∩ R2

55 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple : Voici le résultat de l’intersection des deux relations livre1 et livre2 :

IV-3. La différence : -

La différence consiste à combiner deux relations (compatibles) pour créer une troisième relation qui
contient toutes les occurrences appartenant à l’une des relations et non contenues dans l’autre des
relations de départ. Deux différences sont possibles.

Notation :
 R1 - R2
 R2 – R1

Exemple : Voici le résultat de la différence entre les deux relations livre1 et livre2 :

V. Opérateurs n-aires :

V-1. Produit cartésien : x

Le produit cartésien de R1 par R2 , noté R1  R2, est constitué par l’ensemble des n-uplets obtenus
en concaténant chaque n-uplet de R1 avec chaque n-ulpet de R2 .

Exemple : soit les deux relations suivantes :

Relation R1 Relation R2

NumProd Desig NumFour

P1 Clavier F1
F2
P2 Ecran

Le résultat du produit cartésien de R1 par R2 est la relation T donnée par :


Relation T=R1xR2

56 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

NumProd Desig NumFour


P1 Clavier F1
P1 Clavier F2
P2 Ecran F1

P2 Ecran F2

V-2. Division cartésienne : ÷

La division est une opération portant sur deux relations R1 et R2, telles que le schéma de R2 est
strictement inclus dans celui de R1, qui génère une troisième relation regroupant toutes les parties
d’occurrences de la relation R1 qui, associées à toutes les occurrences de la relation R2, se
retrouvent dans R1.

Exemple : soit les deux relations suivantes :

Relation R1 Relation R2

NumProd Prix Desig Desig

P1 50 Clavier WebCam
Clavier
P2 100 Clavier
P3 20 WebCam
P1 50 WebCam
P2 100 WebCam

Le résultat de la division cartésienne de R1 par R2 est la relation T donnée par :


Relation T=R1 ÷ R2

NumProd Prix
P1 50

P2 100

V-3. Jointure, thêta-jointure, jointure naturelle :

Définition : La jointure est une opération portant sur deux relations R1 et R2 qui construit une
troisième relation regroupant exclusivement toutes les possibilités de combinaison des occurrences
des relations R1 et R2 qui satisfont l’expression logique E.
La jointure est notée : R1 ⋈E R2.

Si R1 ou R2 ou les deux sont vides, alors la relation qui résulte de la jointure est vide. En fait, la
jointure n’est rien d’autre qu’un produit cartésien suivi d’une sélection :
R1 ⋈E R2 = σE (R1 x R2)

57 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exemple : soit les deux relations suivantes :

R1 R2

NumProd Desig NumFour NumFour Nom

P1 PC F1 F1 lamrani
F2 ben said
P2 Imprimante F6
F3 boubekri
P3 scanner F3
F4 chuichi
P4 CD F1

Le résultat de la jointure R1 (R1.NumFour=R2. NumFour) R2 est la relation T donnée par :

NumProd Desig R1.NumFour R2.NumFour Nom


P1 PC F1 F1 lamrani

P3 scanner F3 F3 boubekri

P4 CD F1 F1 lamrani

Thêta-jointure de deux relations n'ayant aucun attribut commun :

La thêta-jointure est une jointure dans laquelle l’expression logique E est une simple comparaison
entre un attribut A1 de la relation R1 et un attribut A2 de la relation R2. La thêta-jointure est notée
R1 ⋈ER2.

Équi-jointure :

Une équi-jointure est une thêta-jointure dans laquelle l’expression logique E est un test d’égalité
entre un attribut A1 de la relation R1 et un attribut A2 de la relation R2. L’équi-jointure est notée R1
⋈A1=A2R2.

Jointure (naturelle) de deux relations ayant au moins un attribut commun.


Une jointure naturelle est une jointure dans laquelle l’expression logique E est un test d’égalité entre
les attributs qui portent le même nom dans les relations R1 et R2. Dans la relation construite, ces
attributs ne sont pas dupliqués, mais fusionnés en une seule colonne par couple d’attributs. La
jointure naturelle est notée R1 ⋈ R2. Si la jointure ne doit porter que sur un sous-ensemble des
attributs communs à R1 et R2 il faut préciser explicitement ces attributs de la manière suivante : R1
⋈ A1, .., An R2.

Généralement, R1 et R2 n’ont qu’un attribut en commun. Dans ce cas, une jointure naturelle est
équivalente à une équi-jointure dans laquelle l’attribut de R1 et celui de R2 sont justement les deux
attributs qui portent le même nom.

Pour effectuer une jointure naturelle entre R1 et R2 sur un attribut A1 commun à R1 et R2, il vaut
mieux écrire R1 ⋈ A1R2 que R1⋈R2. En effet, si R1 et R2 possèdent deux attributs portant un nom

58 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

commun, A1 et A2, R1 ⋈ A1R2 est bien une jointure naturelle sur l’attribut A1, mais R1 ⋈ R2 est une
jointure naturelle sur le couple d’attributs A1, A2, ce qui produit un résultat très différent !

V-4. Opérateurs d’agrégation :

On utilise les opérateurs d’agrégation afin d’exécuter de simples calculs statistiques sur un ensemble
de données. Ces opérateurs font un calcul sur un ensemble de données et retourne une seule valeur.
Les fonctions suivantes sont disponibles :
 COUNT : nombre de valeurs
 MIN : valeur minimum
 MAX : valeur maximum
 SUM : somme des valeurs
 AVG : valeur moyenne.

Notation : R’ = a1, a2, … λ f1, f2, … (R)


 la relation R’ correspond aux valeurs calculées par f1 et f2 des regroupements faits sur les
attributs a1 et a2 de la relation R.
 Si aucun attribut de regroupement n’est spécifié alors les fonctions s’appliquent sur tous les
tuples à la fois.
 Le nom des attributs de sortie est constitué de la concaténation de la fonction et de l’attribut
spécifié.
Exemple : soit la relation suivante :
Eleves R = ville λ Max(Note) R
R
CNE Note Ville
Ville Max_Note
100 12 Tanger
Tanger 13.7
200 16 Casa
Casa 16
300 13.7 Tanger
Fes 5
400 5 Fes

59 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 12 : Algèbre relationnelle

Projection-Sélection-Union-Intersection-Différence

Exercice 1 :

La base de données regroupe un ensemble de relations liées à la gestion des vols d’un aéroport. Le schéma
relationnel de la base est le suivant:
 Pilote(Code pilote, nom, prénom, nombre heures).
 Compagnie(Code Compagnie, nom, origine).
 Avion(Code Avion, type, capacite).
 Vol(Code Vol, Ville départ, Ville arrivée, heure départ, jour départ , heure arrivée, jour arrivée, Code
pilote, Code Avion, Code Compagnie).

Travail à faire:
Pour chaque relation:
1. identifier le domaine de chaque attribut:
2. Les clefs primaires
3. Les clefs externes (étrangères).

Exercice 2 :
On considère les relations suivantes:

Traduire les requêtes suivantes en opérations de l’algèbre relationnelle.

1. Obtenir la liste des filières proposées dans ce lycée.


2. Obtenir toutes les informations concernant les classes de PCSI.
3. Obtenir les prénoms des élèves des classes 1 et 3.
4. Obtenir les noms et les notes des élèves ayant eu une note inférieure à 10.

60 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Exercice 3 :
Soient les deux relations T et S suivantes :
T S
A B D A B
1 2 3 3 4
5 6 7 7 8
1 2 4 1 2

Calculer les expressions suivantes de l’algèbre relationnelle :

1. R = πA,B(T) 7. R∪S
2. σA+B<5(R) 8. R∩S
3. πA(R) 9. R-S
4. R×S 10. S-R
6. R∪R

Exercice 4 :

Soient les relations suivantes :

Donner les résultats des requêtes suivantes :

61 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 13 : Algèbre relationnelle

Projection-Sélection-Union-Intersection-Différence-Produit cartésien-Jointure

EXERCICE 1: Faire du Cinéma ...


On considère les deux relations : :

* LESFILMS(TITRE, PAYS, ANNEE, REALISATEUR, DUREE)

* LESACTEURS(#TITRE, ACTEUR, salaire)

et où les attributs ont les significations et les types suivants:

-TITRE : titre d'un film (chaine 50 caractères)

-PAYS : pays d'où un film est originaire (chaine 10 caractères)

-ANNEE : année de sortie du film (entier 4 chiffres)

-REALISATEUR: Nom du réalisateur du film (chaine 20 caractères)

- DUREE : durée du film en mn (entier 3 chiffres)

-ACTEUR : Nom d'acteur (chaine 20 caractères)

La relation LESFILMS donne pour chaque film identifié par son titre, le pays, l'année de sortie, réalisateur et la
durée.

La relation LESACTEURS donne pour chaque film l'ensemble des principaux acteurs.

A l'aide de l'algèbre relationnelle exprimer les requêtes suivantes:

Q1: Liste des films français (titre, année, réalisateur).

Q2: Donnez les années de sortie des films tournés par ‘GABIN’.

Q3: Trouver les acteurs qui ont tourné avec ‘TRUFFAUT’ comme réalisateur.

Q4: Trouver tous les acteurs qui ont été partenaires de ‘DENEUVE’.

Q5: Liste des films où le réalisateur est aussi acteur

Q6: Réalisateurs ayant joué comme acteurs dans des films qu'ils ne réalisaient pas eux-mêmes.

Q7: Réalisateurs qui ne jouent pas dans un de leur propre film.

62 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Chapitre 6: Langage sql


I. Quelques rappels

Les données constituant la base sont organisées en tables. Une table contient des enregistrements
composés de différents champs. Le type associé au champ défini le domaine sur lequel le champ
pourra prendre ses valeurs (date, entier, chaîne de caractères).

Chaque table est désignée de manière unique par un identificateur (son nom) au sein de la base de
données de même que chaque champ au sein d’une table.

Usuellement on représente une table par un tableau dont les colonnes correspondent aux champs et
les lignes aux enregistrements :

La clé primaire d’une table est un champ (ou un ensemble de champs) qui identifie de manière
unique chaque enregistrement dans la table. Chaque table devrait avoir une clé primaire.

Une clé étrangère dans une table est un champ (ou un ensemble de champs) qui fait référence à un
champ (ou un ensemble de champs) d’une autre table (généralement la clé primaire).

Les requêtes permettent d’interroger une base de données et d’en modifier les informations.

II. Qu'est-ce que SQL ?

Le SQL est un langage de requête structuré (Structured Query Language) destiné à


communiquer avec des bases de données relationnelles implémentées dans des SGBDR (Système
de Gestion de Bases de Données Relationnelles) tels que SQLite, Oracle, Access, SQL Server ou
encore Sybase.
Le langage SQL permet d'effectuer diverses opérations comme la création, l'extraction, la
modification, la suppression, la fusion, etc., sur des collections de données, par l'intermédiaire
d'instructions particulières appelées des commandes, souvent assistées d'ailleurs par des clauses
ou des options.
La première mouture du langage SQL est apparu en 1979, puis sera standardisé à quatre
reprises; en 1986 avec le SQL-ANSI (American National Standard Institute), en 1989 avec SQL-ISO
(International Standard Application) et ANSI, en 1992 avec la seconde version du SQL-ISO et ANSI
et enfin en 1999, pour établir la troisième version.

III. Les commandes SQL :

Les commandes SQL se divisent en trois catégories principales pour : la définition, la


manipulation, l'interrogation des données :

 Le langage de définition : propose des commandes de création (CREATE), suppression


(DROP) et modification (ALTER) de tables, d'index, de contraintes, etc...
 Le langage de Manipulation : permet d'insérer (INSERT), de mettre à jour (UPDATE) des
enregistrements, de supprimer (DELETE) des données, mais également de manipuler des
curseurs (DECLARE, OPEN, FETCH, CLOSE) au sein d'une base de données relationnelles.

63 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 Le langage de requête : fournit une commande de sélection d'enregistrements (SELECT)


qui avec ses très nombreuses clauses et options offrent un support d'interrogation des
bases de données très puissant et complet.

Il existe de nombreuses autres catégories de commandes comme celles explicitées ci-dessous.

 Le langage de contrôle : est utilisé pour la gestion des droits d'accès aux utilisateurs en
attribuant (GRANT) ou révoquant (REVOKE) des privilèges.
 Les commandes d'administration : de données sont utilisées pour la réalisation d'audits
et d'analyses d'opérations sur des bases de données.
 Les commandes transactionnelles : permettant de gérer les transactions de base de
données. Il s'agît de notamment de COMMIT, ROLLBACK, SAVEPOINT et SET
TRANSACTION.

IV. Les commandes DDL:

Les commandes DDL (Data Defintion Language) définissant la structure d'une base de données,
permet la création, la modification ou la suppression de divers objets tels qu'une table, une vue ou
encore un index.

IV-1. La commande CREATE TABLE :

Une base de données relationnelle est composée de tables ou relations constituant un ensemble
logique. Chaque table doit être créée par la commande CREATE TABLE : elle reçoit ainsi un nom et
une structure (liste de noms d'attributs et quelques spécifications). La table existe physiquement
mais elle est encore vide de données. Elle n'est alors qu'une structure logique capable de recevoir
des données

Syntaxe :

CREATE TABLE table


(champ type CONSTRAINT champ propriétés, ... );

Champ Nom du champ (Attribut)


Type Type de données, dans la plupart des versions de SQL, vous aurez droit
aux types de données suivants :
 Char(x) : chaîne de caractères, x est le nombre maximum de caractères
autorisés dans le champ.
 Integer : Nombre entier, positif ou négatif
 Decimal (x,y) : Nombre décimal, x est le nombre maximum de chiffres et y
le nombre maximum de chiffres après la virgule.
Rq : Decimal ne fonctionne pas avec Access, il ne supporte que le type
'float' (flottant), le type float ne permet pas d'indiquer le nombre de
chiffres après ou avant la virgule
 Date : Une date et/ou heure
 Logical – Deux valeurs possibles : oui / non
propriétés Propriétés du champ :
 NULL ou NOT NULL : autorise ou non que le champ puisse être vide.
 UNIQUE : indique que deux enregistrements ne pourront avoir la même
valeur dans ce champ.

64 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

 PRIMARY KEY : indique que ce champ est la clef primaire


 CHECK (condition) : va forcer SQL a faire une vérification de la condition
avant de valider la saisie, exemple : CHECK (prix > 100) interdira la saisie
dans ce champ si la valeur contenue dans le champ prix est inférieure à
100.
Rq : CHECK ne fonctionne pas avec Access.
 DEFAULT = valeur : place une valeur par défaut dans le champ
Rq :ne fonctionne pas avec Access)

Exemple : La commande suivante crée la table " Personnes ", contenant 3 attributs :

CREATE TABLE Personnes


(numero integer , nom CHAR(20) NOT NULL,
prenom CHAR(20),age integer)

Engendre la création de la table ci-dessous :

La clé primaire:

Créons, par exemple, la table "Personnes" avec une clé primaire sur le champ "numero". La
commande s'écrit :
CREATE TABLE Personnes
(numero integer PRIMARY KEY , nom CHAR(20) NOT NULL,
prenom CHAR(20),age integer)

Pour appliquer la clé à deux champs, nous utilisons la syntaxe suivante :

CREATE TABLE Personnes


(numero integer , nom CHAR(20) NOT NULL,
prenom CHAR(20),age integer,
PRIMARY KEY(numero, Nom));
La clé étrangère:

Supposant qu’on a les deux tables suivantes :


 Elève(CNE,Nom,Prénom,#NClasse)
 Classe(NClasse,Nbr_élèves)

Créons la table "Elève" avec une clé primaire sur le champ "CNE" et la clé étrangère sur le champ "
NClasse" La commande s'écrit :

CREATE TABLE Elève


(CNE integer PRIMARY KEY , Nom CHAR(20) , Prénom
CHAR(20), NClasse integer,
FOREIGN KEY (NClasse) REFERENCES Classe (NClasse))

65 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

IV-2. La commande ALTER TABLE :

La commande ALTER TABLE est une requête permettant la modification d'une table en ajoutant,
en supprimant ou en changeant les colonnes, leur définition ou les contraintes.

Syntaxe :

 ajoute les colonnes spécifiées à une table existante.


ALTER TABLE Nom_table ADD colonne type
 supprime la colonne col.
ALTER TABLE Nom_table DROP colonne
 modifie la définition des colonnes spécifiées.
ALTER TABLE Nom_table MODIFY colonne type

Exemple : Il est possible de modifier une table existante. Les exemples les plus classiques concernent
l'addition d'une nouvelle colonne et la suppression d'une colonne existante. La commande :

ALTER TABLE Personnes


ADD Naissance DATE

Permet, lorsqu'on l'exécute, d'ajouter le champ intitulé "Naissance", de type Date/Heure, à la table
"Personnes". La variante suivante fonctionne également :

ALTER TABLE Personnes


ADD COLUMN Naissance DATE

Pour supprimer la colonne que nous venons de créer, nous utilisons la commande suivante :

ALTER TABLE Personnes


DROP Naissance

Ou sa variante :

ALTER TABLE Personnes


DROP COLUMN Naissance

En SQL standard, la commande ALTER TABLE peut aussi être utilisée pour modifier les propriétés
d'une colonne existante.

ALTER TABLE Personnes


MODIFY Nom CHAR(40)

Remarque :

66 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

La clause MODIFY n'est pas reconnue par Access, et l'exécution de la commande ci-dessus
entraîne un message d'erreur. L'ignorance de la clause MODIFY enlève à la commande ALTER TABLE
une bonne partie de son intérêt dans Access.

IV-3. La commande DROP TABLE :

La commande DROP TABLE est une requête permettant la suppression complète d'une table.

Syntaxe :
DROP TABLE Nom_Table

Exemple :
DROP TABLE Personnes

V. Les commandes DML:

Les commandes DML (Data Manipulate Language) permettent de manipuler les informations
d'une base de données.
Il existe trois commandes destinées a mettre à jour (UPDATE), insérer (INSERT) ou supprimer
(DELETE) des données.

V-1. La commande INSERT INTO :

La commande INSERT INTO permet d'ajouter des données dans une table.

Syntaxe :

INSERT INTO Nom_Table


(Champ_1, Champ_2, ..., Champ_N)
VALUES (Valeur_1, Valeur_2, ..., Valeur_N) ;

Les valeurs de colonnes doivent être encadrées par des guillemets simples (') s'il s'agît de chaîne de
caractères, les nombres ne nécessitant pas de guillemets.

Exemple :

INSERT INTO personnes


(numero,nom,prenom,age)
VALUES (1, "Bennani ", "Taj", 18) ;

Il est possible de ne pas énumérer les noms de colonnes si l'ajout de données concerne un
enregistrement complet de la table.

67 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

INSERT INTO Nom_Table


VALUES (Valeur_1, Valeur_2, ..., Valeur_N)

En général, la citation des noms de colonnes est pertinente pour un ajout de données limité à
certain champs de la table.

INSERT INTO Nom_Table


(Champ_1, Champ_2)
VALUES (Valeur_1, Valeur_2)

L'insertion de valeur nulle peut se faire par l'intermédiaire du mot-clé NULL ou d'une chaîne vide.
INSERT INTO Nom_Table
(Champ_1, Champ_2)
VALUES (Valeur_1, NULL)

INSERT INTO Nom_Table


(Champ_1, Champ_2)
VALUES (Valeur_1, '')

V-2. La commande UPDATE :

La commande UPDATE permet de mettre à jour des données existantes au sein d'une table.

Syntaxe :

UPDATE Nom_Table
SET Col_1= Nouv_Val_1, Col_2= Nouv_Val_2,…, Col_N= Nouv_Val_N
WHERE Condition
La commande UPDATE peut mettre à jour les données de manières différentes :

 La valeur d'une seule colonne en ne citant qu'une colonne associée à sa nouvelle valeur.
 Plusieurs colonnes simultanément en citant plusieurs colonnes avec leur valeur respective.
 Par l'intermédiaire d'une clause conditionnelle affectant quelques lignes de données, les
valeurs de plusieurs enregistrements en même temps.

Exemple :

UPDATE Personnes
SET age = 15
WHERE Nom = "Bennani" AND Prenom = "Taj"

68 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

V-3. La commande DELETE FROM :

La commande DELETE FROM permet de supprimer des enregistrements au sein d'une table.
Syntaxe :

DELETE FROM Nom_Table


WHERE Condition

La clause conditionnelle WHERE détermine les enregistrements à sélectionner pour effectuer leur
suppression complète de la table.
Exemple :

DELETE FROM Personnes


WHERE Nom = "Bennani"

Lorsque la clause WHERE est absente, le SGBD supprime tous les enregistrements, laissant la table
vide (mais ne la supprimant pas) :

DELETE FROM Personnes;

VI. Interrogation d’une base :

COMMANDES COMMENTAIRE EXEMPLES


SELECT Opérateur de projection, permettant de Affiche le nom et le prénom de tous les
choisir les colonnes à afficher Suivi de noms de élèves
colonnes ou de * (indiquant toutes les SELECT NomE, PrenomE
colonnes) FROM ELEVES
FROM Suivi d'une ou plusieurs noms de table. La Affiche tous les articles (toutes les
présence de plusieurs tables réalise le produit colonnes)
cartésien de ces tables. SELECT *
FROM Article
WHERE Opérateur de sélection, qui permet de Affiche la designation de tous les
choisir des lignes selon certains critères articles de la commande numéro 1258
(séparés par AND ou OR) SELECT art_designation
Cet opérateur permet aussi de réaliser des FROM Article, Commande
jointures, le plus souvent par égalité des WHERE Article.art_num =
deux colonnes de sens identique dans les Commande.art_num
deux tables. AND num_com = 1258
Critère de jointure
Critère de sélection
DISTINCT La clause DISTINCT permet d’éliminer les Afficher toutes les villes où habite au
doublons : si dans le résultat plusieurs moins un élève
lignes sont identiques, une seule sera SELECT DISTINCT VilleE
conservée FROM ELEVES
ORDER BY La clause ORDER BY permet de trier les Afficher la liste des employés par
résultats par ordre croissant (ASC) ou salaire décroissant
décroissant (DESC). SELECT NomEmp, sal FROM EMPLOYE
Le tri peut se faire sur une ou plusieurs ORDER BY sal DESC
colonnes Afficher les élèves par ordre

69 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

L’option ASC est prise par défaut pour chacune alphabétique du nom
des expressions citées puis du prénom
SELECT * FROM ELEVES
ORDER BY NomE, PrenomE
' Les cotes sont obligatoires pour entourer les Recherche tout les articles de couleur
chaînes de caractère et les dates. rouges :
Sur Access on utilise ‘’ pour les chaînes et SELECT art_num FROM Article
# # pour les dates WHERE art_coul = ‘ ROUGE’

SELECT NumE FROM ELEVES


WHERE ddn = '12/10/1980'
IN IN indique si la valeur est égale à l'une de Liste des employés occupant la
celles qui se trouve entre parenthèse fonction de programmeur, analyste ou
On peut utiliser aussi NOT IN (la valeur développeur
n'est égale à aucune de celles de la liste) SELECT NomEmp , NumEmp FROM
EMPLOYE
WHERE fonction IN ('programmeur',
'analyste',
developpeur');
NULL Indique une valeur non définie (pas entrée). Afficher le nom des professeurs dont
Attention, 0 n'est pas une valeur NULL on ne connaît pas le prénom
L'opérateur de comparaison est IS ou IS SELECT NomP
NOT FROM PROFS
WHERE PrenomP IS NULL
LIKE Permet de comparer une valeur avec une Recherche tout les noms commençant
chaîne non complète par DE :
% désigne plusieurs caractères SELECT NomC, PrenomC, RueC
_ désigne un seul caractère quelconque (ou FROM COMMERCANTS
aucun) WHERE NomC LIKE 'DE% '
Sous Access on utilise * à la place de %
BETWEEN Indique si une valeur est comprise entre Articles qui coutent entre 10 et 20 €
deux valeurs. Les extrêmes sont inclus dans inclus.
l'intervalle. Select art_num, art_lib
FROM Article
WHERE prix BETWEEN 10 AND 20
OPERATEURS Permet d'afficher le résultat d'un calcul à Affiche la référence et la marge de tous
DE CALCUL : partir d'une ou plusieurs colonnes les produits
+-*… SELECT refprod, (prix_vente –
prix_achat) as marge
FROM PRODUIT

OPERATEURS D'AGREGATION

COMMANDES COMMENTAIRE EXEMPLES


COUNT (*) Permet de compter le nombre de lignes Compte le nombre d'élève habitant
résultant d'un résultat. On peut nommer la Tanger et appelle le résultat
colonne correspondante avec AS. Nb_Tanger.
SELECT COUNT (*) AS Nb_Tanger
FROM ELEVES
WHERE VilleE = 'Tanger'
SUM (colonne) Permet d'additionner les valeurs d'une Calcul le cumul (la somme) de tous les

70 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

colonne numérique pour les lignes opérations de débit du compte 1259 le


sélectionnées 09/01/04
SELECT SUM(montant_opération) AS
débit_0901
FROM OPERATIONS
WHERE compte = '1259'
AND date = '09/01/04'
AVG (colonne) Permet d'afficher la moyenne des valeurs Afficher le salaire moyen des analystes
d'une colonne numérique pour les lignes SELECT AVG(salaire)
sélectionnées FROM EMPLOYE
WHERE fonction = 'analyste'

MAX (colonne), Permet d'obtenir la valeur maximale (ou Affiche le salaire de la secrétaire la
MIN (colonne minimale) d'une colonne pour un ensemble mieux payée:
de lignes sélectionnées SELECT MAX(salaire)
FROM EMPLOYE
WHERE function = "secrétaire"

OPERATEURS ENSEMBLISTES

COMMANDES COMMENTAIRE EXEMPLES


UNION Il est possible de faire l’union des résultats La liste des villes où habitent des
de deux requêtes. L'union élimine les élèvent et des
doublons professeurs :
On a alors : A ∪ B SELECT VilleE
FROM ELEVES
UNION
SELECT VilleP
FROM PROFS

INTERSECT Il est possible de faire l’intersection des La liste des villes où habitent à la fois
résultats de deux requêtes. des élèves et
On a alors : A ∩ B des professeurs :
SELECT DISTINCT VilleE
FROM ELEVES
INTERSECT
SELECT DISTINCT VilleP
FROM PROFS
EXCEPT ou Il est possible de faire la différence des La liste des villes où habitent
MINUS résultats de deux requêtes. seulement des élèves et
On a alors : A – B pas de professeurs :
SELECT DISTINCT VilleE
FROM ELEVES
EXCEPT
SELECT DISTINCT VilleP
FROM PROFS

71 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

VII. Interroger une base de données depuis un programme écrit en Python:

Nous allons voir sur un exemple comment effectuer une requête SQL depuis un programme écrit en
Python et comment on récupère le résultat.

import sqlite3 # importer le module sqlite3


con=sqlite3.connect(‘entreprise.sqlite’) #ouverture de la base de données ‘entreprise.sqlite’
c=con.cursor() #obtention d’un curseur
r=‘select * from client’ #Préparer la requête
c.execute(r) # exécution de la requête
#affichage des enregistrements récupérés par fetchall()
L=c.fetchall()
print(L)

for x in L:
print(x[0], x[1],x[2])
con.close() #fermeture de la base

Résultat de ce code :

[ (1, 'Lamrani', 'najib', '1980-01-01 00:00:00', 'sifa', 10000, 'Rabat'), (2, 'Talbi', 'mohamed', '1981-07-
06 00:00:00', 'rafaoui', 80000, 'Sidi kacem'), (3, 'maradani', 'omar', '1977-06-04 00:00:00',
'myalichrif', 80000, 'Rabat'), (4, 'farid', 'omar', '1979-06-03 00:00:00', 'atlass', 70000, 'Sidi Slimane'),
(5, 'bouthir', 'abdelmajid', '1980-09-19 00:00:00', 'boustoh', 80000, 'Sidi kacem'), (6, 'boubekri',
'mohamed', '1979-10-22 00:00:00', 'boudir', 60000, 'Tanger'), (7, 'albakali', 'nadia', '1989-12-03
00:00:00', 'enakhil', 80000, 'Sidi kacem'), (8, 'lasri', 'fatima', '1963-06-11 00:00:00', 'rabat', 93150,
'Tetouan'), (9, 'chuichi', 'mohamed', '1981-06-23 00:00:00', 'sidi youssef', 90000, 'Sidi Slimane'), (10,
'chuichi', 'najib', '1978-08-23 00:00:00', 'lbour', 50000, 'Kenitra'), (11, 'kacha', 'najib', '1963-01-06
00:00:00', 'ghandi', 90000, 'Tanger')]
1 Lamrani najib
2 Talbi mohamed
3 maradani omar
4 farid omar
5 bouthir abdelmajid
6 boubekri mohamed
7 albakali nadia
8 lasri fatima
9 chuichi mohamed
10 chuichi najib
11 kacha najib

72 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n°14 : Langage sql

Une entreprise veut assurer un suivi régulier de ses commandes, c’est dans ce cadre que son
responsable des achats et des ventes, qui prend en charge la passation des commandes, a décidé
d’informatiser le processus des achats. Cependant il a créé une base de données qui comprend toutes les
informations qui s’avèrent nécessaires pour faire le suivi. Les tables qui constituent la base de données sont
les suivantes :
 Client(NumCli, Nom, Prenom, DateNaiss, Rue, CP, Ville)
 Produit(NumProd, Desi, PrixUni, #NumFour, QuantStock)
 fournisseur (NumFour, NomF, PrenomF, Tel, RaisonSoc)
 commande (#NumCli, #NumProd, DateC, Quantite)

1. Lancer FireFox
2. Lancer SQLite Manager
3. Donner les requêtes SQL qui permettent de créer ces 4 tables
4. Donner les requêtes SQL qui permettent de remplir les 4 tables

Après la création et le remplissage de la base de données, le responsable des achats et des ventes veut
interroger et manipuler ces données, et pour se faire il faut créer les requêtes suivantes :

5. Créer une nouvelle table nommée « BonLivraison » qui contient les champs
suivants :NumBL,DateL,NumFour.
6. Remplir la table nommée « BonLivraison » avec enregistrements suivants : (102,06/01/2003,50) .
7. Changer le NumBL=102 par NumBL=104 .
8. Supprimer le deuxième enregistrement de la table « BonLivraison »
9. Détruire la table « BonLivraison ».
10. Majorer de 10% le prix de tous les produits.
11. Supprimer les produits dont le PrixUni≤100
12. Détruire la table « Fournisseur »
13. Visualiser la liste des fournisseurs (NumFour, RaisonSoc)
14. Consulter le stock de l’entreprise : afficher la liste des produits disponibles au sein de l’entreprise (
NumProd, Dési, PrixUni, NumFour).
15. Afficher la liste des commandes triées par date de commande en ordre croissant.
16. Consulter les informations d’un fournisseur donné : (par exemple le fournisseur ayant le prénom :
« hamid » (afficher son téléphone et son nom).
17. Visualiser les fournisseurs dont le nom commence par « N ».
18. Rechercher un produit spécifié, par exemple « souris » (donner le prix unitaire et la quantité en stock).

73 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

19. Afficher les produits ayant la quantité en stock inférieure à 50 .


20. Visualiser les produits dont le prix est supérieur à 2000 DH.
21. Rechercher les produits qui comportent entre 10 à 20 unités en stock.
22. Consulter les commandes des produits reçus en 2001.
23. Calculer le prix total de chaque produit ( ajouter un champ calculé nommé : « prix total » qui est égal
à [prix unitaire] * [quantité en stock] ).
24. Majorer de 10% le prix de tous les produits et mettre le résultat dans un champ nommé « Prix
Majoré ».
25. Quel est le client qui a commandé la plus grande quantité ?
26. Quels sont la quantité minimale et le client qui l’a commandé?
27. Donner les noms des fournisseurs et les produits qu’ils fournissent.
28. Quelle est la moyenne des prix unitaires ?
29. Quel est le nombre des fournisseurs ?
30. Quels sont les fournisseurs qui n’ont fourni aucun produit ?
31. Quel est le prix tolal des produits en stock ?
32. Donner la liste des commandes avec les numéros et les noms des clients.
33. Quels sont les clients ayant le même nom que les fournisseurs.
34. Afficher les clients (NumCli, Nom, Prénom) qui ont commandés le 02/01/2004.
35. Afficher toutes les commandes sous forme (Nom et Prénom du client, Désignation et Prix unitaire du
produit, Date de commande, Quantité commandée).
36. Quels sont les produits commandés par chaque client et leurs fournisseurs (NumFour, Nom,
RaisonSoc, Tél), et les trier par ordre croissant.
37. Afficher les clients et les fournisseurs ayant le même nom ainsi que la quantité commandée par ces
clients et qui se trouve en stock.
38. Quels sont les clients qui habitent à Tétouan ?
39. Quels sont les clients qui habitent à Tanger ?
40. Quels sont les clients qui habitent à Tétouan et Tanger?
41. Parmi les clients qui habitent à Tétouan et Tanger, quels sont ceux qui ont le même nom?

74 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n°15 : Langage sqL

Soit le schéma de base de données relationnel « gestion des ventes » suivant


CLIENT(NClient, Nom, Ville, Tel)
FOURNISSEUR(Nfour, Nom , Ville , Tel)
FOURNIR(#Nfour, #Nproduit , Prix)
ACHETER(#NClient, #Nproduit ,date_achat, Quantité)
PRODUIT(Nproduit, Nom , Stock , Prix)
____: clé primaire
#: Clé étrangère

Ecrivez en SQL les requêtes suivantes :

1. Les clients qui habitent à Paris


2. Le nom et N° de tel des fournisseurs qui habitent à ‘‘Rabat’’ ou ‘‘Paris’’
3. Le nom, le prix et le stock des Produits
4. Les noms des produits en stock
5. Les noms des produits dont le prix et entre 243,89 dh et 989,34dh
6. Les noms des produits vendus le 06/12/2014.
7. Le nom et la ville des clients et les noms des produits achetés
8. Le nombre des produits, Le prix maximal, le prix minimal et la moyenne des prix des produits.
9. Les noms des produits fournis par chaque fournisseur
10. Les noms des clients noms triés par ordre croissant
11. Le nombre des clients par ville
12. Le produit le plus vendu
13. Le produit le moins vendu

75 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

Série n° 16 : Langage sql/Python

Interroger une base de données depuis Python [ module sqlite3 ]

Rappel sur Python : les tuples

Vous avez vu en première année la notion de liste en Python. Par exemple, [1, 3, 42] est une liste Python à
3 éléments, qui sont les nombres 1, 3 et 42. Python a un deuxième concept très similaire : les tuples
(ou N-uplets en bon français). Un tuple s’écrit comme une liste, mais en remplaçant les crochets ([]) par des
parenthèses.
 La principale différence avec les listes est qu’un tuple n’est pas modifiable (on ne peut pas changer le
nombre d’éléments, ni les éléments eux-mêmes)
 On peut bien sûr imbriquer les tuples et les listes : [(1, 2), (3, 4)] est une liste qui contient deux
doublets (tuples à 2 éléments).
 Dans le cas particulier des tuples à 1 seul élément, on utilise la syntaxe (element,) pour éviter
l’ambiguïté avec les parenthèses de groupement. Par exemple, (42) est le nombre 42, alors que (42,)
est un tuple contenant le nombre 42.

Exercice 1 :
Soit la liste M suivante :
M = [ (’stylo ’, ’bleu ’, True ),(’gomme ’, ’rouge ’, True ), (’feutre ’, ’vert ’, False) ]

Écrire et tester la fonction description_trousse qui prend en paramètre une liste M et qui affiche le texte
suivant :
Dans ma trousse, il y a :
- stylo bleu
- gomme rouge
Exercice 2 :
On veut gérer la base de données music.sqlite, à travers le module sqlite3 du langage Python
Dans la base de données music.sqlite on trouve les relations suivantes :
 Artistes (idArtiste, nomArtiste)
 Disques (idDisque, pays, #idArtiste, nomDisque,typeDisque ,annee,mois, jour)
 Morceaux (idMorceau, #idDisque,#pays, #idArtiste,nomMorceau,longueur)
 Version (dateMiseAJour, contributeur)

1) Écrivez une fonction CreerArtistes(NomBase) prenant en paramètre le nom de la base de données et qui
permet de créer la table Artistes

2) Écrivez une fonction RemplirArtistes(NomBase,NomF) prenant en paramètre le nom de la base de


données et le nom d’un fichier csv et qui permet de remplir la table Artistes par les données du fichier.
Le fichier csv a le format suivant :

3) Écrivez une fonction liste_Disques(NomBase) prenant en paramètre le nom de la base de données et


renvoyant la liste des disques sortis en 2015

76 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>


Spé: Algorithmique et programmation 2/ BD CPGE TANGER

4) Écrivez une fonction liste_Artistes(NomBase,s) prenant en paramètre le nom de la base de données et


une chaîne de caractères et renvoyant la liste des identifiants d’artistes dont le nom est passé en
paramètre. Le tout doit être classé par ordre décroissant

5) Écrivez une fonction RechercheDisques(NomBase,x) prenant en paramètre le nom de la base de données


et un identifiant d’artiste et renvoyant la liste de tous ses disques (albums et autres).

6) Écrivez une fonction ExporterArtistes(NomBase,NomF) prenant en paramètre le nom de la base de


données et le nom d’un fichier csv et qui permet d’exporter le contenu de la table Artistes vers un fichier
csv

77 Prof : ZBAKH ABDEL ALI <zbakhabdou@gmail.com>

Vous aimerez peut-être aussi