Université Mohammed V-Agdal École Supérieure de Technologie Salé

Slides:



Advertisements
Présentations similaires
ORTHOGRAM PM 3 ou 4 Ecrire: « a » ou « à » Référentiel page 6
Advertisements

LES NOMBRES PREMIERS ET COMPOSÉS
Module Systèmes d’exploitation
GEF 243B Programmation informatique appliquée Listes chaînées I – Tableaux de structures §15.1 – 15.2.
Tris.
Chapitre 3 Les arbres binaires
Portée des variables VBA & Excel
Fonctions & procédures
GEF 243B Programmation informatique appliquée Listes chaînées II §15.1 – 15.2.
GEF 243B Programmation informatique appliquée
Cours n°2M2. IST-IE (S. Sidhom) UE 303 Promo. M2 IST-IE 2005/06 Conception dun système d'information multimédia Architecture trois-tiers : PHP/MySQL &
C.
Algorithme et structure de données
Chap. 1 Structures séquentielles : listes linéaires
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
FLSI602 Génie Informatique et Réseaux
Initiation à la programmation et algorithmique cours 3
Mr: Lamloum Med LES NOMBRES PREMIERS ET COMPOSÉS Mr: Lamloum Med.
Développement d’applications web
Cours 7 - Les pointeurs, l'allocation dynamique, les listes chaînées
Structures de données linéaires
Récursivité.
44 Contrôle du déroulement du programme. 4-2 Objectifs A la fin de ce cours, vous serez capables de : Utiliser les constructions de prise de décision.
Les structures de données arborescentes
Synchronisation et communication entre processus
II. Chaînage, SDD séquentielles
Cours de physique générale I Ph 11
8PRO100 Éléments de programmation Allocation dynamique de la mémoire.
II. Chaînage, SDD séquentielles
Détection de co-évolution de gènes Master 2 : Informatique à Finalité Professionnelle et Recherche Unifiée (IFPRU) Parcours Ingénierie de lIntelligence.
TRAITEMENT DE STRUCTURES
Définition d’un maillon de liste
IFT-2000: Structures de Données Listes chaînées Dominic Genest, 2009.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Académie de Créteil - B.C Quest-ce quune Inscription 1)1 action + 1 stagiaire + 1 client 2)Parcours individuel (avec son Prix de Vente) 3)Un financement.
F Copyright © Oracle Corporation, Tous droits réservés. Créer des programmes avec Procedure Builder.
LES NOMBRES PREMIERS ET COMPOSÉS
Les pointeurs Enormément utilisé en C/C++ ! Pourquoi? A quoi ça sert?
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
1 INETOP
Introduction à l’algorithmique
Représentation des systèmes dynamiques dans l’espace d’état
Représentation des systèmes dynamiques dans l’espace d’état
Représentation des systèmes dynamiques dans l’espace d’état
DUMP GAUCHE INTERFERENCES AVEC BOITIERS IFS D.G. – Le – 1/56.
8PRO100 Éléments de programmation Les types composés.
Équipe 2626 Octobre 2011 Jean Lavoie ing. M.Sc.A.
Plan cours La notion de pointeur et d’adresse mémoire.
Exemple de gestion d'un buffer clavier en liste circulaire
Structures des données
Le langage C Structures de données
Traitement de différentes préoccupations Le 28 octobre et 4 novembre 2010.
1/65 微距摄影 美丽的微距摄影 Encore une belle leçon de Macrophotographies venant du Soleil Levant Louis.
Equation différentielle de 2ème ordre
Le langage C Rappel Pointeurs & Allocation de mémoire.
Ch. PAUL - Piles et Files à l'aide de listes chainées
LES PILES ET FILES.
Les Pointeurs et les Tableaux Statiques et Tableaux Dynamiques
Notions de pointeurs en C
et quelques rappels sur certains éléments du langage C
Les Chiffres Prêts?
Introduction à l’informatique en gestion 1 Plan de la leçon Compagnon office Sections et Mise en page En-têtes et pieds de page Notes de bas.
Tutorat en bio-informatique Le 14 novembre Au programme… Les objets –Propriétés (attributs) –Constructeurs –Méthodes.
II. Chaînage, SDD séquentielles
ISBN Chapitre 10 L'implémentation des sous- programmes.
Cours LCS N°4 Présenté par Mr: LALLALI
Classe 1 CSI2572 Autres modificateurs de déclaration de variables: & volatile & register & static & auto & extern & const volatile Indique au compilateur.
 Chaînage et LSC : motivation et principe Manipuler la LSC : exemples Variantes : LDC, liste circulaire, … Etude de cas : réalisation d’un buffer clavier.
Informatique 2A Langage C 5ème séance. Déroulement de la séance 5 1 ère partie Étude des chaînes de caractères 2 ème partie Les structures 3.
Transcription de la présentation:

Université Mohammed V-Agdal École Supérieure de Technologie Salé STRUCTURE DE DONNEES … F. Guerouate

Chapitre-1 Listes chaînées

Définition … Introduction Les listes chaînées sont des structures dont le nombre d’éléments de même type peut varier au cours de l’exécution du programme. Les éléments consécutifs seront tout simplement chaînés entre eux. Il existe plusieurs types de listes chaînées dépendant de la manière dont on se déplace dans la liste, les listes chaînées simples, les listes doublement chaînées, les listes circulaires.

Les listes chaînées simples … Dans une liste chaînée, un élément est la donnée d’un couple (P, V) , place valeur. Sur une liste chaînée on peut définir trois fonctions :         * Une fonction qui permet de retourner le 1er élément de la liste         * Une fonction qui permet de retourner le successeur d’un élément dans la liste * Une fonction qui permet de retourner la valeur de l’élément si bien sur la place de ce dernier est connue Convention graphique Valeur de l’élément. Place de l ‘élément suivant dans la liste, place est de type pointeur. valeur place

Représentation graphique d’une liste chaînée dernier valeur ~= NIL premier element Pointeur sur l’élément suivant Déclaration du type pointeur struct elem { int valeur ; struct elem * suivant ; } ; typedef struct elem liste;

struct elem. suivant ; déclare un pointeur sur la données suivante struct elem *suivant ; déclare un pointeur sur la données suivante. « suivant » est le nom du pointeur (vous pouvez donc mettre n'importe quel nom) et c'est là qu'on découvre à quoi sert l'étiquette. En effet à ce stade le nom de la structure n'est pas encore donné. Toutefois le pointeur va pointer sur un nouvel élément, donc sur une instance de la structure que l'on est justement en train de définir. On utilise donc l'étiquette précédée du mot clef « struct ». element : il s'agit tout simplement du nom final donnée à la structure. Sur la ligne suivant : on déclare un nouveau type qui est un pointeur vers un element et que l'on appelle « liste ». Cette opération est facultative mais elle accrôit sensiblement la lisibilité du programme.

Accès aux valeurs de la liste … L'accès à la valeur d'une variable d'un élément donné se fait en reprenant les notations de structure composée. Exemple liste *l ; int a ; a=(*l).valeur ; liste *l ; int a ; a=l->valeur ; Ou L'accès au(x) pointeur(s) se fera de la même façon : l->suivant.

Initialiser la liste chaînée … Pour cela on utilise l'instruction « malloc » associé à « sizeof » : liste *l ; l=(liste*)malloc(sizeof(liste)); Notre liste est maintenant initialisée. « l » sera un pointeur sur le premier élément. On peut désormais affecter une valeur à cet élément. Il est important de se souvenir qu'il faudra réserver de la mémoire, donc faire un malloc, à chaque fois que l'on voudra insérer un nouvel élément, à l'emplacement de l'élément.

Saisie de plusieurs éléments … Admettons que l'utilisateur est entrée au clavier la valeur d'une variable entière «n» indiquant le nombre d'élément à créer. Le programme de saisie pourrait être celui-ci : Liste *l,*laux ; //on déclare également une variable auxiliaire qui va nous servir pour parcourir la liste l=(liste*)malloc(sizeof(element)) ;//on initialise c'est à dire on fait pointer l sur l'espace mémoire réservé pour le premier element laux=l ; //on fait pointer laux au même endroit que l

for(i=1 ;i<n+1 ;i++) { //on doit saisir n valeurs scanf("%d",laux->valeur) ; //saisie de la valeur //on fait pointer le pointeur suivant sur un nouvel espace réservé laux->suivant=(liste*)malloc(sizeof(element)) ; if(i==n) laux->suivant=NULL ; //on fait pointer le dernier élément sur un pointeur NULL afin d'avoir un programme plus « propre » laux=laux->suivant ; //on fait pointer laux sur le nouvel espace créé afin de saisir la valeur du prochain élément au prochain tour de boucle ; }

Attention Il ne faut surtout pas utiliser le pointeur principal « l » pour parcourir les éléments de la liste. Sinon on perdrai l'adresse du premier élément et donc de toute la liste chaînée. on utilise toujours un pointeur de parcours (liste auxiliaire) Il est important de savoir qu'il faut toujours faire l'allocation de mémoire AVANT d'ordonner au pointeur de pointer sur un élément.

Si on avait écrit : laux=laux->suivant ; laux=(liste*)malloc(sizeof(element)) ; de même que : laux=l ; l=(liste*)malloc(sizeof(element)) ; la compilation aurait fonctionné mais l'exécution non. En effet l'adressage du pointeur change au moment de l'allocation de la mémoire. Ceci représente une erreur type. Il faut y faire attention ! N'oubliez pas non plus que toute saisie d'un nouvel élément doit être précédée d'une allocation de mémoire.

En pratique, la saisie se fait rarement par une boucle mais par un appel successif d'une fonction définie par l'utilisateur qui saisie un élément en début ou en fin de liste suivant les cas. Il n'est pas obligatoire mais il est fortement recommandé de terminer la liste par le pointeur NULL (sauf en cas de liste cyclique, où le dernier pointeur pointe sur le premier élément). A noter l'existence de la fonction free() ; qui libère la place assignée par un malloc. Ex : free(l) ;

Les opérations sur les listes … Les opérations sur les listes sont très nombreuses, parmi elles : - Créer une liste vide - Tester si une liste est vide - Ajouter un élément à la liste · ajouter en début de liste (tête de liste) · ajouter à la fin de la liste (queue) · ajouter un élément à une position donnée · ajouter un élément après une position donnée . ajouter un élément avant une position donnée

- Afficher ou imprimer les éléments d'une liste - Ajouter un élément dans une liste triée (par ordre ascendant ou descendant) - Supprimer un élément d’une liste · supprimer en début de liste · supprimer en fin de liste ·  supprimer un élément à une position donnée . supprimer un élément avant ou après une position donnée.

Parcours d’une liste chaînée … Il existe une liste chaînée d’entiers, préalablement déclarée But : Afficher dans l’ordre de la liste tous les éléments de la liste : 5-10-15-20-25 5 10 15 20 25 l laux l.valeur l.suivant Remarque : Penser à dupliquer la valeur du premier pointeur (laux).

Algorithme   Var *l, *laux : liste  Début laux :=l TQ ( laux<>NULL ) FAIRE Sortir (laux->valeur) laux:= laux->suivant FTQ Remarque : Quand on cherche le dernier élément d‘une liste, le test à effectué est (laux->suivant) <>null. Le test laux<>null permet de parcourir indifféremment tous les éléments de la liste.

Ajout en tête de liste quand la liste n’est vide … Exemple  : On suppose que l’on veut rajouter l’élément 6 au début de la liste suivante : 4 3 5 8 2 l a)- on commence par créer le nouveau nœud et lui donner son contenu 6 laux

b)- le suivant de p est l’ancienne tête de liste 6 4 3 5 8 2 laux l b)- on fait pointer le pointeur l vers la tête de liste   6 4 3 5 8 2 l

Les opérations a, b et c se traduisent par le pseudo-code suivant : Allouer (laux) Laux-> valeur := 6 Laux-> suivant := l l := laux Remarque : Si la liste est vide, cet algorithme convient aussi sous réserve d’avoir correctement initialiser premier

Ajout en fin de liste (liste non vide) … a)- on cherche le dernier élément de la liste, pour cela on utilise un pointeur de parcours. b)- création du nouveau bloc à insérer dans la liste.(nouveau) c)- lier le nouveau bloc à la liste.

q := l  TQ (q ->Suivant <>nil) FAIRE q := q -> Suivant FTQ Allouer (nouveau) Entrer (nouveau ->Valeur) nouveau ->suivant := nil  q ->suivant := nouveau

Dans cette situation, le pointeur nouveau n’est pas indispensable car le pointeur de parcours q pointe sur le dernier bloc.Comment ? . Allouer (q-> Suivant) q := q-> Suivant q-> Suivant := nil entrer (q -> valeur)

Ajout dans une liste chaînée … Ajout d’un élément après un nœud pointé par p p q La recherche a été effectuée est fournie le pointeur sur le bloc qui précède celui à insérer.

a)- création du nouveau bloc b)- mise à jour des liens. Allouer (nouveau) Entrer (nouveau -> Valeur)  nouveau ->Suivant := laux-> suivant Laux->suivant := nouveau

Ajout d’un élément avant un nœud pointé par p 17 -6 9 34 Vers le nouvel élément Si la valeur du nouvel élément est -5, le successeur du prédécesseur de p (-6) devient le nouvel élément (-5), or nous ne pouvons pas remonter un pointeur à reculons, il faudrait repartir au début de la liste. Une solution serait d’insérer le nœud après p et transférer la valeur de nœud p dans le nouvel élément.

17 -6 -5 9 34 Noter qu’avec cette solution le pointeur p qui pointait vers le nœud contenant 9 avant l’insertion du nouvel élément, pointe vers le nœud contenant –5 après l’insertion du nouvel élément.

Suppression dans une liste chaînée … On ne peut pas détruire un élément dans une liste vide. Suppression en tête de liste -5 15 35 45 l Temp l := l-> Suivant   Si on se content de cette instruction, le programme a logiquement éliminé de la liste le premier bloc, mais celui-ci est toujours en mémoire. De ce fait, il occupe inutilement de la place mémoire. Il faut donc libérer cette place mémoire.

La fonction free, en langage C, permet de libérer cette place mémoire La fonction free, en langage C, permet de libérer cette place mémoire. Cette fonction prend un paramètre en l’occurrence, le pointeur de bloc qui doit être supprimé. Temp := l l := l-> Suivant Libérer (Temp) (Temp ne pointe sur rien du tout)

Suppression en fin de liste a)- Parcours de la liste à le recherche du dernier élément (sous réserve d’avoir en mémoire l’adresse du dernier élément). b)- L’avant dernier bloc de la liste devient le dernier. c)- On libère le bloc à supprimer. dernier := l TQ (dernier-> Suivant) <> nil FAIRE l := dernier dernier := dernier-> Suivant FTQ  l-> Suivant := nil Libérer (dernier)

Cet algorithme ne fonctionne pas si la liste est vide.

Suppression à un endroit quelconque de la liste a)- Recherche du bloc qui précède le bloc à supprimer. b)- Construire le lien qui unis le bloc qui précède le bloc à détruire et le bloc qui le succède. c)- Détruire. parcours := l TQ (parcours->suivant <> R) FAIRE parcours := parcours->Suivant FTQ  parcours-> Suivant := R -> Suivant  Libérer ( R )

LISTES PARTICULIERES …

LISTES BILATERES … Définition Dans les listes simplement chaînées, à partir d'un nœud donné, on ne peut accéder qu'au successeur de ce nœud. Dans une liste doublement chaînée (ou bilaterè), à partir d'un nœud donné, on peut accéder au nœud successeur et au nœud prédécesseur. Les éléments d’une liste bilatère contiennent 2 pointeurs : *un pointeur sur le bloc suivant *un pointeur sur le bloc précédent 30 35 34 Tête Courant Queue

Déclaration des types de données nécessaires struct elem { int valeur ; struct elem * suivant; struct elem  *precedent; } ; typedef struct elem * liste;

Construction De La Liste A)- liste vide l : =NIL B)- Ajout du premier élément allouer(l) l->suivant:=NIL L->prec=NULL entrer (l->valeur) C)- Ajout entête de liste si la liste n’est pas vide. ALLOUER (laux) laux->suivant : =l l->précédent : = laux laux->précédent : = NIL laux->valeur : = 1 l : =laux

D)- Ajout en fin de liste dans les listes bilatères. But : insérer une valeur dans une liste triée en ordre croissant a)- Phase de parcours (à la recherche du dernier bloc). b)- Création du nouveau bloc (à insérer). d)- Mise à jour des liens.

laux : =l ; TQ laux->suivant <> NIL faire laux: =laux->suivant FTQ  Allouer (nouveau) Entrer (nouveau-> Valeur) nouveau->suivant : = NIL nouveau->précédent : = laux Laux->suivant : = nouveau

E)- Ajout à un endroit qcq de la liste. 20 10 23 12 Courant

laux : = l TQ laux-> Valeur <>20 FAIRE laux : = laux->suivant FTQ  Allouer (nouveau) Entrer (nouveau->valeur) nouveau->précédent : = laux nouveau ->suivant : = laux->suivant Laux->suivant ->précédent : = nouveau Laux->suivant : = nouveau

Destruction dans une liste bilatère … Suppression en tête de liste (*) toujours s’assurer qu’il existe 1 elt dans la liste. laux :=l l:= l->suivant  //l->suivant->précédent : =NIL Dispose (laux) //Libérer (l-> Précédent) l->Précédent : = NIL

Suppression en fin de liste laux :=l TQ laux->suivant <>NIL faire laux :=laux->suivant FTQ Laux->précédent->suivant : =NIL Libérer(laux) Attention cet algorithme n’est valable que si la liste contient plus d’un élément.

Suppression à un endroit quelconque de la liste s->precedent>suivant=s-> suivant s ->suivant ->precedent: =s->precedent libérer (s).

LISTES CIRCULAIRES …

Définition Une liste où le pointeur NUL du dernier élément est remplacé par l’adresse du premier élément est appelée liste circulaire. Dans une liste circulaire tous les nœuds sont accessibles à partir de n’importe quel autre nœud. Une liste circulaire n’a pas de premier et de dernier nœud. Une liste circulaire peut être simplement chaînée ou doublement chaînée. Noter que la concaténation de deux listes circulaires peut se faire sans avoir à parcourir les deux listes.

Déclaration des types de données nécessaires typedef struct elem { int valeur ; struct elem * suivant;} element ; typedef element * anneau;