cours informatique 2 version 0.0 _2

publicité
LA RÉCURSIVITÉ
QU’EST-CE QUE LA RÉCURSIVITÉ ?
Un sous-programme(fonction ou procédure) est dit récursifs’ il s’appelle lui-même
directement ou indirectement.
Exemple
La fonction suivante calcule la factorielle n! D’un nombre n. On se base sur la
relation de récurrence n! = (n − 1)! ∗n. en c
Fonction FactorielleRécursive(n: entier)
Début
Si (n=0) alors
return 1;
sinon
return n*FactorielleRecursive(n-1)
finsi
fin
int FactorielleRecursive(int n)
{if (n <= 0)
return 1;
else
return n*FactorielleRecursive(n-1); /* appel récursif */
}
L’appel d’une fonction à l’intérieur d’elle-même est nommé appel récursif. Un appel
récursif doit obligatoirement être dans une instruction conditionnelle (sinon la
récursivité est sans fin).
Remarque
1. tout programme récursif peut implémenter manière itérative (en utilisant les
boucles).
2. les programmes récursifs sont plus simplesàécrire et à lire.
3. les programme récursive sont inefficaces comparativement au programme
itérative.
1
STRUCTURE DE DONNEES DYNAMIQUES
Motivations (problématique) :
supposons qu’on a souhaité gérer une liste d’objets.
la solution traditionnelle consiste à les représenter sous forme d’un tableau .donc on
va avoir les déclarations suivantes :
Type objet record
début
……
fin
var t tableau[ n ] : objet ;
on doit déclarer la taille n comme une constante
comme exemple : Soit T l’ensemble des étudiants d’un groupe donnée
l’ensemble des éléments du tableau T peuvent être ordonnées ; cette solution
présente plusieurs problèmes
1. problème de taille .
2. insertion d’un élément dans le cas ou T est triée .
3. suppression d’un élément( des trous dans T ).
solution
la solution à ces problèmes consiste à ne pas utiliser des variables statiques ( comme
les tableaux ) et à utiliser des variables dont la taille change au cours de l’exécution
du programme.
principe : réservation de l’espace mémoire si on a besoin et libération de l’espace si
on n’a pas besoin.
2) pointeur :le concept de pointeur est essentiel pour la gestion dynamique d’un
ensemble d’objet.
un pointeur est un variable dont les valeurs admissibles sont des adresses mémoires .
donc , on a besoin d’un nouveau type qui correspond au pointeur .
il n’ya pas dans les langages de programmation un nouveau type pour déclarer un
pointeur .
maisils nous donnent un autre moyen pour les déclarer
exemple : soit x ,y deux variables entiers ( int x ,y ; ), supposons qu’on va définir des
variables px , py pour pointer sur x et y.
var x , y : entier ;
px , py : ↑entier ;
en c
int x,y ;
int *px, *py ;
int t[ 10 ] ; // ( t est un pointeur reçoit la première adresse du tableau « *t le contenu
de 1er adresse équivalent t[0] »)
2
on peut écrire
px = &x ;
py = &y ;
x = * py ( xreçoit le contenu « * » de l’adresse trouver dans py « équivalente x = y » ).
px = py ;
*px = ( *px) +1 ; ( équivalente x = x+1 )
px= t ;
*px = ( *px +1) ; ( équivalente t[0] = t[1] ou *t = ( *t +1) ) ;
LISTES CHAÎNÉES
Une liste chaînée est un ensemble des objets liés entre eux par des pointeurs. Chaque
objet est une structure contenant les champs suivants :
• une ou plusieurs données comme dans n’importe quelle structure ;
• un pointeur suivant sur la cellule suivante.
On accède à la liste par un pointeur L sur le premier élément, puis en parcourant la
liste d’un élément à l’autre en suivant les pointeurs suivant. Le dernier pointeur
suivant vaut NULL, ce qui indique la fin de la liste.
L
elem1
elem2
….
elem n NULL
DÉCLARER UNE LISTE CHAÎNÉE
Pour créer une liste chaînée, il faut déclarer une nouvelle structure de données : la
structure qui représentera un élément.
/* exemple : les données dans les éléments sont des nombres réelles */
Typedef struct elem
{
Floatdonnee;
elem *suivant; /* pointeur sur la structure suivante de type elem */
}elem;
La structure elem contient un pointeur suivantsurelem.
On déclare ensuite le pointeur sommet qui donne l’adresse du premier
élément comme suit
elem*sommet ; /* déclaration d’une liste */
la liste est vide suit a l’exécution de l’instruction sommet=NULL ;
3
1. Insertion d’un élément
les étapesnécessaires pour ajouter un élément la liste sont
1. réserver un espace mémoire dont l’adresse est stocké dans un pointeur p.
2. affectation des données vers les champs données
3. insertion effective de l’élément dans la liste.
opérations 1 : cette opération se réalise par l’appel vers une fonction de compilateur
(fonction système) new ( p ) ( réserver un espace mémoire et mettre son adresse dans p)
p doit êtredéclaré avant utiliser comme suit Var p :↑elem ;
en langage c on utilise la fonction malloc comme suit
p=(elem *)malloc(sizeof(elem)) ; (réserver un espace mémoire de taille correspond
au type elem )
opérations 2 : des affectations classiques
opérations 3 : dans le cas d’insertion au début
p↑.suivant ← sommet ;
sommet ← p ;
2. suppression d’un élément
opérationsnécessaires
1. trouver l’élément p à supprimé en parcourant la liste a partir du sommet( recherche
dans la liste).
2. faire sortir l’élément depuis la liste en manipulant le contenu des pointeurs
3. libération de l’espace mémoire.
Operations 1 :
x←sommet ;
prec←sommet ;
Tantque( x ≠ p et x ≠ NULL)
prec←x ;
x←x↑.suivant ;
fin-tantque
si (x=p) alors
l’élément existe ;
sinon
l’élément n’existe pas ;
finsi
Operations 2 :
prec↑.suivant ←x↑.suivant ;
Operations 3 :
free( p ) ;
4
Remarque :
selon l’opération insérer un élément dans une liste chainée, le nouvel élémentinséré
devient toujours le premier ; et si l’élément a supprimé devient toujours le premier ;
ce type de liste suit une stratégie dite FILO ( First In Last Out « premier arrivée
dernier à servir »)ou LIFO ( Last In First Out « dernier arrivée premier à servir »).
cette stratégie est utilisée pour gérer une structure particulière appelée « PILE» (
STUCK ).
LES PILES
Une pile est une structure (dynamique) qui suit la stratégie FILO ( First In Last Out
)
opérations sur les piles :on a 4 opérations
Empiler (Push) : insérer un élémentE dans une pile P Empiler( E, P ) ;
Depiler (POP) : faire sortir un élément depuis une pile P Depiler( P ) ;
Sommet (TOP) : retourne la valeur stockée dans le sommet de la pile P Sommet( p) ;
Est_vide (Is-Empty) : retourne vrai (1) si la pile P est vide, faux (0) sinon Est_vide ( p ) ;
En c
Codes operations :
Type elem record
{
Float donnee;
elem*suivant;
}elem;
1.
Fonction est_vide( L :↑elem) : booléen
Debut
Si (L=NULL) alors
Return( vrai) ;
Sinon
Return( faux) ;
finsi
fin
2.
Fonction Sommet ( L :↑elem) : réel
Debut
Return( L↑.donnee) ;
Fin
Typedefstructelem
{
Float donnee;
elem *suivant;
}elem;
int est_vide(elem *L)
{ if (L==NULL)
Return 1 ;
Else
Return 0 ;
}
2.
Float Sommet( elem *L)
{
Return ( L→donnee ) ;
}
3.
5
Procedure Empiler (varL :↑elem , inf : reel )
Vare : ↑elem ;
Debut
Reserver( e ) ;
e↑.donnee←inf ;
e↑.suivant← L ;
L=e ;
Fin
3.
Void Empiler (elem **L ,floatinf)
{ elem *e ;
e=(elem *)malloc(sizeof(elem)) ;
e→donnee=inf ;
e→suivant= *L ;
*L= e ;
4.
Procedure Depiler (L :↑elem)
Vare : ↑elem ;
Debut
e←L;
L← L↑.suivant;
Libérer (e) ;
Fin
}
4.
Void Depiler (elem **L )
{ elem *e ;
e=*L ;
*L =*L →suivant;
Free(e) ;
}
RQ :
L’aspect contrôle a été laissé au programme appelant .
LES FILES
Une file est une structures de données dans laquelle on peut ajouter et supprimer
des éléments suivant la règle du premier arrivé premier sorti, ou encore FIFO (First
In First Out)
Le nom de file vient d’une analogie avec une file d’attente à un guichet, dans laquelle
le premier arrivé sera le premier servi. Les usagers arrivent en queue de file, et sortent
de la file à sa tête.
Tète
elem1
elem2
….
elem n NULL
Queue
.opérationsapplicablesur les Files :on a 4 opérations
Enfiler: insérer un élément E dans une File F Enfiler( E, F ) ;
Défiler: faire sortir un élément depuis une File FDéfiler( F ) ;
Premier : retourne la valeur stockée dans le premier élémentde la File FPremier ( F) ;
Dernier : retourne la valeur stockée dans le premier élément de la File F Dernier ( F) ;
Est_vide: retourne vrai (1) si la file F est vide , faux (0) sinon Est_vide ( F ) ;
6
Codedes opérations :
Type elem record
debut
var donnee :réel;
suivant :↑elem ;
fin
Type file record
debut
var tete:↑elem ;
queue: :↑elem ;
fin
1.
Fonction est_vide( L : file ) : booléen
Debut
Si (L.tete=NULL) alors
Return( vrai) ;
Sinon
Return( faux) ;
finsi
fin
2.
Procedure Enfiler (varL :file , inf : reel )
Vare : ↑elem ;
Debut
Reserver( e ) ;
e↑.donnee←inf ;
e↑.suivant←L.tete ;
si(est_vide (L)=vrai) alors
L.tete←e ;
L.queue← e ;
sinon
L↑.tete← e ;
finsi
Fin
3.
Procedure Defiler (varL : file)
Debut
L.tete← L.tete ↑.suivant;
si(est_vide (L)=vrai) alors
L.queue ← L. tete ;
Finsi Fin
En c
Typedefstructelem
{
Float donnee;
elem *suivant;
}elem;
Typedefstruct file
{ elem *tete;
elem *queue;
}elem;
int est_vide(file L)
{ if (L.tete==NULL)
Return 1 ;
Else
Return 0 ;
}
2.
Void Enfiler (file *L, float inf)
{ elem *e ;
e=(elem *)malloc(sizeof(elem)) ;
e→donnee = inf ;
e→suivant= *L.tete ;
if(est_vide (*L)==1)
{*L.tete= e ;
*L.queue= e ;
}
Else
*L.tete= e ;
3.
}
VoidDefiler (file *L )
{ *L.tete= *L.tete →suivant;
if(est_vide (*L)==1)
{ *L.queue= NULL ;
}
}
7
LES ARBRES
Les Arbres sont des structures de donneeshierarchiques
un arbre est un ensemble de nœuds inter connectés par des arcs.
cettedefinition concerne ce qu’on appelle « Graphes »
définition
un graphe G est un ensemble de sommets reliés par des arcs G = ( V , E )ou :
V : l’ensemble des sommets (nœuds) = { v1 , v2, v3 ,…, vn }
E : { (v1 , v2) , (v1 , v5) ,(v2 , v4 ) ,(v 3 , v 2) ,……,(vi,vj) }
chaqueelement de E est un couple (vi, vj) représente une connexion depuis vi vers vj
définition
un arbre est un graphe avec la particularité suivante :
nœud « racine » : a partir du quel on peut accéder aux autres nœuds qui sont classés
en sous arbres disjoints .
notation :
un nœud est soit :
1. racine
2. feuille
3. interne
pour un nœud quelconque V , on trouve
le père de V : le nœud de niveau inferieur a partir du quel on accede a V.
le fils de V : le nœud de niveau suivant accessible à partir de V.
pour programmer ce genre de structures de données , on doit en premier lieu
procéderà la déclaration
8
Téléchargement