end - LIFL
Transcription
end - LIFL
Algorithmique et Programmation Impérative 2 Enregistrements, Pointeurs, Structures chaînées N.E. Oussous [email protected] FIL – USTL API2 - LST«A» – p.1/42 Introduction ➻ Structurer les données pour mieux les manipuler API2 - LST«A» – p.2/42 Introduction ➻ Structurer les données pour mieux les manipuler ➻ Si les données sont homogènes (même type) API2 - LST«A» – p.2/42 Introduction ➻ Structurer les données pour mieux les manipuler ➻ Si les données sont homogènes (même type) ➠ on peut utiliser un tableau API2 - LST«A» – p.2/42 Introduction ➻ Structurer les données pour mieux les manipuler ➻ Si les données sont homogènes (même type) ➠ on peut utiliser un tableau ➻ Si les données sont hétérogènes (de types différents) API2 - LST«A» – p.2/42 Introduction ➻ Structurer les données pour mieux les manipuler ➻ Si les données sont homogènes (même type) ➠ on peut utiliser un tableau ➻ Si les données sont hétérogènes (de types différents) ➠ on utilise une structure d’enregistrement API2 - LST«A» – p.2/42 Exemple Un employé d’une entreprise peut être défini par ➻ son nom (chaîne de caractères) API2 - LST«A» – p.3/42 Exemple Un employé d’une entreprise peut être défini par ➻ son nom (chaîne de caractères) ➻ son adresse (chaîne de caractères) API2 - LST«A» – p.3/42 Exemple Un employé d’une entreprise peut être défini par ➻ son nom (chaîne de caractères) ➻ son adresse (chaîne de caractères) ➻ son salaire (réel) API2 - LST«A» – p.3/42 Exemple NOM ADRESSE employé Un employé d’une entreprise peut être défini par ➻ son nom (chaîne de caractères) ➻ son adresse (chaîne de caractères) ➻ son salaire (réel) Notons ➻ NOM l’ensemble des noms ➻ ADRESSE l’ensemble des adresses ➻ SALAIRE l’ensemble des salaires Alors SALAIRE (un triplet) API2 - LST«A» – p.3/42 Enregistrement Enregistrement = structure = article = record ➻ Pour représenter les -uplets API2 - LST«A» – p.4/42 Enregistrement Enregistrement = structure = article = record ➻ Pour représenter les -uplets ➻ C’est un objet constitué de composants nommés pouvant être de types différents API2 - LST«A» – p.4/42 Enregistrement Enregistrement = structure = article = record ➻ Pour représenter les -uplets ➻ C’est un objet constitué de composants nommés pouvant être de types différents ➻ En Pascal Enregistrement=Record API2 - LST«A» – p.4/42 Enregistrement Enregistrement = structure = article = record ➻ Pour représenter les -uplets ➻ C’est un objet constitué de composants nommés pouvant être de types différents ➻ En Pascal Enregistrement=Record Syntaxe : type <nom_du_type> = record <nom_du_champ_1> : <type_du_champ_1> ; <nom_du_champ_2> : <type_du_champ_2> ; ... end {record} ; API2 - LST«A» – p.4/42 Déclaration, Accès type T_HEURE = 0..23 ; T_MINUTE = 0..59 ; T_SECONDE = 0..59 ; T_HORAIRE = record h : T_HEURE ; m : T_MINUTE ; s : T_SECONDE ; end {record} ; h1, h2 : T_HORAIRE ; Ainsi, le type T_HORAIRE est un type composé de champs de types différents. Les champs du type T_HORAIRE sont nommés h, m et s. API2 - LST«A» – p.5/42 Déclaration, Accès On peut faire les opérations suivantes : var h1,h2 : T_HORAIRE ; |with h1 do begin h1.h := 10 ; | h := 10 ; h1.m := 35 ; | m := 35 ; h1.s := 20 ; | s := 20 ; |end ; h2 := h1 ; API2 - LST«A» – p.6/42 Déclaration, Accès On peut faire les opérations suivantes : var h1,h2 : T_HORAIRE ; |with h1 do begin h1.h := 10 ; | h := 10 ; h1.m := 35 ; | m := 35 ; h1.s := 20 ; | s := 20 ; |end ; h2 := h1 ; ➻ On accède aux champs avec la notation pointée API2 - LST«A» – p.6/42 Déclaration, Accès On peut faire les opérations suivantes : var h1,h2 : T_HORAIRE ; |with h1 do begin h1.h := 10 ; | h := 10 ; h1.m := 35 ; | m := 35 ; h1.s := 20 ; | s := 20 ; |end ; h2 := h1 ; ➻ On accède aux champs avec la notation pointée ➻ On peut affecter un enregistrement en bloc API2 - LST«A» – p.6/42 Déclaration, Accès On peut faire les opérations suivantes : var h1,h2 : T_HORAIRE ; |with h1 do begin h1.h := 10 ; | h := 10 ; h1.m := 35 ; | m := 35 ; h1.s := 20 ; | s := 20 ; |end ; h2 := h1 ; ➻ On accède aux champs avec la notation pointée ➻ On peut affecter un enregistrement en bloc ➻ On ne peut pas comparer 2 enregistrements API2 - LST«A» – p.6/42 Déclaration, Accès On peut faire les opérations suivantes : var h1,h2 : T_HORAIRE ; |with h1 do begin h1.h := 10 ; | h := 10 ; h1.m := 35 ; | m := 35 ; h1.s := 20 ; | s := 20 ; |end ; h2 := h1 ; ➻ ➻ ➻ ➻ On accède aux champs avec la notation pointée On peut affecter un enregistrement en bloc On ne peut pas comparer 2 enregistrements On évitera les types anonymes ! API2 - LST«A» – p.6/42 Déclaration de constante On peut déclarer des constantes typées : const <nom_const> : <nom_du_type>=<valeur_const>; API2 - LST«A» – p.7/42 Déclaration de constante On peut déclarer des constantes typées : const <nom_const> : <nom_du_type>=<valeur_const>; Exemple : const DEPART : T_HORAIRE = (h:8; m:30; s:0); API2 - LST«A» – p.7/42 Déclaration de constante On peut déclarer des constantes typées : const <nom_const> : <nom_du_type>=<valeur_const>; Exemple : const DEPART : T_HORAIRE = (h:8; m:30; s:0); Attention ! si h est une variable, on ne peut pas écrire h := (h:10 ; m:0; s:0) ; API2 - LST«A» – p.7/42 Un autre exemple type T_JOURS = (Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche) ; T_QUANTIEME = 1..31 ; T_MOIS = (Janvier, Fevrier, Mars, Avril, Mai, Juin, Juillet, Aout, Septembre, Octobre, Novembre, Decembre); T_ANNEE = Cardinal ; T_DATE = record jour : T_JOUR ; quantieme : T_QUANTIEME ; mois : T_MOIS ; annee : T_ANNEE ; end {record} ; API2 - LST«A» – p.8/42 Article avec partie variable ➻ Une partie de la structure est fixée pour tous les les objets API2 - LST«A» – p.9/42 Article avec partie variable ➻ Une partie de la structure est fixée pour tous les les objets ➻ Le reste peut prendre plusieurs formes différentes. D’où les articles avec partie variable API2 - LST«A» – p.9/42 Article avec partie variable ➻ Une partie de la structure est fixée pour tous les les objets ➻ Le reste peut prendre plusieurs formes différentes. D’où les articles avec partie variable ➻ Le choix entre les différentes alternatives est gouverné par la valeur d’un discriminant API2 - LST«A» – p.9/42 Article avec partie variable ➻ Une partie de la structure est fixée pour tous les les objets ➻ Le reste peut prendre plusieurs formes différentes. D’où les articles avec partie variable ➻ Le choix entre les différentes alternatives est gouverné par la valeur d’un discriminant ➻ La partie variable ressemble à une instruction case API2 - LST«A» – p.9/42 Article avec partie variable ➻ Une partie de la structure est fixée pour tous les les objets ➻ Le reste peut prendre plusieurs formes différentes. D’où les articles avec partie variable ➻ Le choix entre les différentes alternatives est gouverné par la valeur d’un discriminant ➻ La partie variable ressemble à une instruction case ➻ Elle vient après les autres champs API2 - LST«A» – p.9/42 Syntaxe type <nom_du_type> = record <nom_champ_1> : <nom_type_1> ; ... <nom_champ_n> : <nom_type_n> ; case selecteur : <type_scalaire> of <liste_const_1> : (<variante_1>) ; ... <liste_const_n> : (<variante_n>) ; end ; <variante_k> est de la forme : <nom_champ_1> : <nom_type_1> ; ... <nom_champ_m> : <nom_type_m> ; API2 - LST«A» – p.10/42 Exemple type T_NOM = String[20] ; T_GENRE = (Masculin, Feminin) ; T_INDIVIDU = record nom : T_NOM ; naissance : T_DATE ; // date de naissance case sexe : T_GENRE of Masculin : (Barbu : boolean) ; Feminin : (Enfants : Cardinal) ; end ; API2 - LST«A» – p.11/42 Déclaration de constante const TOTO : T_INDIVIDU = (nom : ’Toto’ ; naissance : (jour quantieme mois annee sexe : Masculin ; barbu : true ) ; : : : : VENDREDI; 11 ; MARS ; 2005) ; API2 - LST«A» – p.12/42 Utilisation procedure putIndividu(const ind: T_INDIVIDU) ; begin with ind do begin write(nom,’ : ’) ; with naissance do begin putJour(jour); write(quantieme,’ ’); putMois(mois); write(annee) ; end ; // with writeln ; case sexe of Masculin : begin write(’Barbu: ’) ; if barbu then write(’oui’) else write(’non’); end ; Feminin : write(’Enfants: ’,enfants) ; end ; // case end ; // with writeln ; end ; // putIndividu API2 - LST«A» – p.13/42 Struct. de données dynamiques ➻ La définition et l’utilisation d’un type de données (TD) permet de fixer une fois pour toutes le domaine des valeurs possibles pour les variables et par conséquent leur format en mémoire. On a ainsi des valeurs statiques. API2 - LST«A» – p.14/42 Struct. de données dynamiques ➻ La définition et l’utilisation d’un type de données (TD) permet de fixer une fois pour toutes le domaine des valeurs possibles pour les variables et par conséquent leur format en mémoire. On a ainsi des valeurs statiques. ➻ Si les valeurs et les structures des variables changent pendant le calcul, elles deviennent dynamiques. API2 - LST«A» – p.14/42 Struct. de données dynamiques ➻ La définition et l’utilisation d’un type de données (TD) permet de fixer une fois pour toutes le domaine des valeurs possibles pour les variables et par conséquent leur format en mémoire. On a ainsi des valeurs statiques. ➻ Si les valeurs et les structures des variables changent pendant le calcul, elles deviennent dynamiques. ➻ Les composants de telles structures sont à un niveau de résolution donné statiques. API2 - LST«A» – p.14/42 Algorithmes Données A LGORITHMES instruction élémentaire D ONNÉES type scalaire (non structuré) (non structurée) briques de base pour instructions composées types de données composites API2 - LST«A» – p.15/42 Algorithmes Données A LGORITHMES instruction élémentaire D ONNÉES type scalaire (non structuré) (non structurée) briques de base pour instructions composées A LGORITHMES instructions composées types de données composites D ONNÉES type enregistrement nombre fini de composants qui peuvent être de natures différentes API2 - LST«A» – p.15/42 Algorithmes Données A LGORITHMES for (répétition un nombre fini et connu de fois) D ONNÉES type tableau (nombre fini et connu d’éléments de même type) API2 - LST«A» – p.16/42 Algorithmes Données A LGORITHMES for (répétition un nombre fini et connu de fois) D ONNÉES type tableau (nombre fini et connu d’éléments de même type) A LGORITHMES D ONNÉES choix parmi deux ou plusieurs if ou case type enregistrement avec variante API2 - LST«A» – p.16/42 Algorithmes A LGORITHMES Données D ONNÉES répétition un nombre initialement inconnu de fois while ou loop suite ou fichier forme simple pour construire des types de cardinalité “infinie" API2 - LST«A» – p.17/42 Algorithmes Données A LGORITHMES D ONNÉES répétition un nombre initialement inconnu de fois while ou loop suite ou fichier forme simple pour construire des types de cardinalité “infinie" A LGORITHMES D ONNÉES récursivité Procédure directement Types de données ou indirectement récursive récursifs API2 - LST«A» – p.17/42 Algorithmes Données A LGORITHMES D ONNÉES répétition un nombre initialement inconnu de fois while ou loop suite ou fichier forme simple pour construire des types de cardinalité “infinie" A LGORITHMES D ONNÉES récursivité Procédure directement Types de données ou indirectement récursive récursifs Pour définir les types récursifs, on utilisera les pointeurs. API2 - LST«A» – p.17/42 Pointeurs ➻ La propriété caractéristique des Structures de Données Récursives (SDR) est leur faculté de varier de taille. API2 - LST«A» – p.18/42 Pointeurs ➻ La propriété caractéristique des Structures de Données Récursives (SDR) est leur faculté de varier de taille. ➻ On n’affecte pas de quantité fixe de mémoire à une SDR. Donc le compilateur ne peut pas associer une adresse spécifique aux composants de telles variables. API2 - LST«A» – p.18/42 Pointeurs ➻ La propriété caractéristique des Structures de Données Récursives (SDR) est leur faculté de varier de taille. ➻ On n’affecte pas de quantité fixe de mémoire à une SDR. Donc le compilateur ne peut pas associer une adresse spécifique aux composants de telles variables. ➻ La technique utilisée est l’allocation dynamique de mémoire. API2 - LST«A» – p.18/42 Pointeurs ➻ La propriété caractéristique des Structures de Données Récursives (SDR) est leur faculté de varier de taille. ➻ On n’affecte pas de quantité fixe de mémoire à une SDR. Donc le compilateur ne peut pas associer une adresse spécifique aux composants de telles variables. ➻ La technique utilisée est l’allocation dynamique de mémoire. ➻ Une quantité fixe de mémoire, juste assez pour contenir l’adresse du composant dynamiquement alloué, à la place du composant lui-même. API2 - LST«A» – p.18/42 Les pointeurs en Pascal ➻ Un pointeur est une variable qui désigne une adresse mémoire. API2 - LST«A» – p.19/42 Les pointeurs en Pascal ➻ Un pointeur est une variable qui désigne une adresse mémoire. ➻ Quand un pointeur contient l’adresse d’une autre variable, on dit qu’il pointe sur l’emplacement en mémoire de cette variable. API2 - LST«A» – p.19/42 Les pointeurs en Pascal ➻ Un pointeur est une variable qui désigne une adresse mémoire. ➻ Quand un pointeur contient l’adresse d’une autre variable, on dit qu’il pointe sur l’emplacement en mémoire de cette variable. ➻ Un pointeur de tableau contient l’adresse du premier élément du tableau. API2 - LST«A» – p.19/42 Les pointeurs en Pascal ➻ Un pointeur est une variable qui désigne une adresse mémoire. ➻ Quand un pointeur contient l’adresse d’une autre variable, on dit qu’il pointe sur l’emplacement en mémoire de cette variable. ➻ Un pointeur de tableau contient l’adresse du premier élément du tableau. ➻ Les pointeurs sont typés pour indiquer le type de données stockées à l’adresse qu’ils contiennent. API2 - LST«A» – p.19/42 Les pointeurs en Pascal ➻ Un pointeur est une variable qui désigne une adresse mémoire. ➻ Quand un pointeur contient l’adresse d’une autre variable, on dit qu’il pointe sur l’emplacement en mémoire de cette variable. ➻ Un pointeur de tableau contient l’adresse du premier élément du tableau. ➻ Les pointeurs sont typés pour indiquer le type de données stockées à l’adresse qu’ils contiennent. ➻ Les pointeurs occupent 4 octets en mémoire. API2 - LST«A» – p.19/42 Comprendre les pointeurs Soit le code suivant : var X, Y: Integer ; // variables entières P: ^Integer ; // P pointe sur un entier begin X := 3 ; // X reçoit la valeur 3 P := @X ; // P contient l’adresse de X Y := P^ ; // Y reçoit la valeur contenue // à l’adresse P end ; API2 - LST«A» – p.20/42 Comprendre les pointeurs ➻ @ permet d’avoir l’adresse d’une variable. API2 - LST«A» – p.21/42 Comprendre les pointeurs ➻ @ permet d’avoir l’adresse d’une variable. ➻ mis devant un nom de type permet de définir un type pointeur sur des variables de ce type. nom_Type_Defini API2 - LST«A» – p.21/42 Comprendre les pointeurs ➻ @ permet d’avoir l’adresse d’une variable. ➻ mis devant un nom de type permet de définir un type pointeur sur des variables de ce type. ➻ nom_Type_Defini mis après une varaible pointeur, P , il déréférence le pointeur : il renvoie la valeur contenue à l’adresse contenue dans le pointeur. API2 - LST«A» – p.21/42 Comprendre les pointeurs ➻ @ permet d’avoir l’adresse d’une variable. ➻ mis devant un nom de type permet de définir un type pointeur sur des variables de ce type. ➻ nom_Type_Defini mis après une varaible pointeur, P , il déréférence le pointeur : il renvoie la valeur contenue à l’adresse contenue dans le pointeur. ➻ Avec la déclaration : type nom_Type_Ptr = type_Defini ; Les valeurs de type nom_Type_Ptr sont des pointeurs vers des données de type type_Defini. API2 - LST«A» – p.21/42 Comprendre les pointeurs ➻ @ permet d’avoir l’adresse d’une variable. ➻ mis devant un nom de type permet de définir un type pointeur sur des variables de ce type. ➻ nom_Type_Defini mis après une varaible pointeur, P , il déréférence le pointeur : il renvoie la valeur contenue à l’adresse contenue dans le pointeur. ➻ Avec la déclaration : type nom_Type_Ptr = type_Defini ; Les valeurs de type nom_Type_Ptr sont des pointeurs vers des données de type type_Defini. ➻ Les valeurs de type pointeur sont générées chaque fois qu’un élément de donnée est alloué dynamiquement. API2 - LST«A» – p.21/42 Pointeurs : Création ➻ Pour créer une donnée pointée, de type nom_Type_Ptr, on utilise la procédure new : new(P) ; API2 - LST«A» – p.22/42 Pointeurs : Création ➻ Pour créer une donnée pointée, de type nom_Type_Ptr, on utilise la procédure new : new(P) ; ➻ Cette procédure alloue effectivement une variable de type type_Defini et affecte le pointeur désignant cette variable à P. API2 - LST«A» – p.22/42 Pointeurs : Création ➻ Pour créer une donnée pointée, de type nom_Type_Ptr, on utilise la procédure new : new(P) ; ➻ Cette procédure alloue effectivement une variable de type type_Defini et affecte le pointeur désignant cette variable à P. ➻ On étend le domaine des valeurs de tous les types pointeurs par une valeur unique qui ne pointe sur aucun élément : nil. API2 - LST«A» – p.22/42 Pointeurs : Création ➻ Pour créer une donnée pointée, de type nom_Type_Ptr, on utilise la procédure new : new(P) ; ➻ Cette procédure alloue effectivement une variable de type type_Defini et affecte le pointeur désignant cette variable à P. ➻ On étend le domaine des valeurs de tous les types pointeurs par une valeur unique qui ne pointe sur aucun élément : nil. ➻ On peut donc engendrer des structures finies sans avoir besoin de la présence explicite de variantes dans leur déclaration (récursive). API2 - LST«A» – p.22/42 Exemple type PtrMonome = ^Monome ; Monome = record coef : Real; // coefficient deg : Integer ; // degré suiv : PtrMonome ; end; // record procedure getMonome(out M: PtrMonome) ; begin new(P) ; with P^ do begin write(’Coefficient: ’) ; readln(coef) ; write(’Degre: ’) ; readln(deg) ; suiv := nil ; end; // with end; // getMonome API2 - LST«A» – p.23/42 Pointeurs : Restitution ➻ Il peut y avoir ou non un ramasse-miettes. Quoiqu’il en soit, on peut préférer faire notre propre ménage. API2 - LST«A» – p.24/42 Pointeurs : Restitution ➻ Il peut y avoir ou non un ramasse-miettes. Quoiqu’il en soit, on peut préférer faire notre propre ménage. ➻ On peut le réaliser au moyen de la procédure dispose API2 - LST«A» – p.24/42 Pointeurs : Restitution ➻ Il peut y avoir ou non un ramasse-miettes. Quoiqu’il en soit, on peut préférer faire notre propre ménage. ➻ On peut le réaliser au moyen de la procédure dispose ➻ L’instruction dispose(P) libère la place pointée par P. API2 - LST«A» – p.24/42 Pointeurs : Restitution ➻ Il peut y avoir ou non un ramasse-miettes. Quoiqu’il en soit, on peut préférer faire notre propre ménage. ➻ On peut le réaliser au moyen de la procédure dispose ➻ L’instruction dispose(P) libère la place pointée par P. ➻ Après un appel à dispose, la valeur de P est indéterminée. P n’est pas mise à nil. API2 - LST«A» – p.24/42 Pointeurs : Restitution ➻ Les deux procédures new et dispose utilisent une zone mémoire appelée TAS. API2 - LST«A» – p.25/42 Pointeurs : Restitution ➻ Les deux procédures new et dispose utilisent une zone mémoire appelée TAS. ➻ new prend une place du TAS et dispose restitue une place au TAS. API2 - LST«A» – p.25/42 Pointeurs : Restitution ➻ Les deux procédures new et dispose utilisent une zone mémoire appelée TAS. ➻ new prend une place du TAS et dispose restitue une place au TAS. ➻ Ce «TAS» cessera d’exister quand on sera hors de la portée du type poiteur. API2 - LST«A» – p.25/42 Pointeurs : Restitution ➻ Les deux procédures new et dispose utilisent une zone mémoire appelée TAS. ➻ new prend une place du TAS et dispose restitue une place au TAS. ➻ Ce «TAS» cessera d’exister quand on sera hors de la portée du type poiteur. ➻ Le programmeur doit gérer l’allocation-libération de la place mais le système s’occupe lui-même de la gestion interne du TAS. API2 - LST«A» – p.25/42 Listes chaînées en Delphi ➻ On peut créer une séquence d’éléments liés entre-eux et tels que chaque élément contient API2 - LST«A» – p.26/42 Listes chaînées en Delphi ➻ On peut créer une séquence d’éléments liés entre-eux et tels que chaque élément contient ➠ une partie utile : l’information proprement-dite API2 - LST«A» – p.26/42 Listes chaînées en Delphi ➻ On peut créer une séquence d’éléments liés entre-eux et tels que chaque élément contient ➠ une partie utile : l’information proprement-dite ➠ un lien vers l’élément suivant (s’il existe) : ce lien est l’adresse de l’élément suivant. API2 - LST«A» – p.26/42 Listes chaînées en Delphi ➻ On peut créer une séquence d’éléments liés entre-eux et tels que chaque élément contient ➠ une partie utile : l’information proprement-dite ➠ un lien vers l’élément suivant (s’il existe) : ce lien est l’adresse de l’élément suivant. ➻ Pour désigner une liste, il suffit d’avoir l’adresse de son premier élément (tête de liste). API2 - LST«A» – p.26/42 Listes chaînées en Delphi ➻ On peut créer une séquence d’éléments liés entre-eux et tels que chaque élément contient ➠ une partie utile : l’information proprement-dite ➠ un lien vers l’élément suivant (s’il existe) : ce lien est l’adresse de l’élément suivant. ➻ Pour désigner une liste, il suffit d’avoir l’adresse de son premier élément (tête de liste). ➻ De ce premier élément, on peut consulter, séquentiellement, tous les autres éléments. API2 - LST«A» – p.26/42 Exemple 1 Une liste d’entiers : type PtrNoeud = ^Noeud ; Noeud = record info : Integer ; // par exemple suiv : PtrNoeud; end ; Liste = PtrNoeud ; var L P: Liste ; 1 2 3 4 nil API2 - LST«A» – p.27/42 Exemple 2 Un polynôme à coefficients réels : type PtrMonome = ^Monome ; Monome = record coef : Real ; // coefficient deg : Integer ;// degré suiv : PtrMonome ; end ; Polynome = PtrMonome ; var P: Polynome ; 3.5 1 5.1 3 1.0 5 nil 0 2.0 P API2 - LST«A» – p.28/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P ➻ Il s’agit de mettre P en tête de liste API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P ➻ Il s’agit de mettre P en tête de liste L P 1 2 3 4 nil 0 API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P ➻ Il s’agit de mettre P en tête de liste L 1 2 3 4 nil 1 P 0 API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P ➻ Il s’agit de mettre P en tête de liste L 1 2 2 3 4 nil 1 P 0 API2 - LST«A» – p.29/42 Ajout en tête ➻ On se donne une liste (i.e. son pointeur de tête L) ➻ On se donne un élément donné par un pointeur P ➻ Il s’agit de mettre P en tête de liste L 1 2 P 3 4 nil 1 P L 2 0 0 1 2 3 4 nil API2 - LST«A» – p.29/42 Ajout en tête type PtrNoeud = ^Noeud ; Noeud = record info : Integer ; suiv : PtrNoeud end; // record List = PtrNoeud ; procedure headAdd(var L:list;var P:PtrNoeud); begin P^.suiv := L ; L := P ; end; // headAdd API2 - LST«A» – p.30/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. ➻ Il s’agit de mettre P en queue de liste API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. ➻ Il s’agit de mettre P en queue de liste Q L 1 2 3 P 4 nil 0 nil API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. ➻ Il s’agit de mettre P en queue de liste Q L 1 2 3 P 4 nil 0 nil API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. ➻ Il s’agit de mettre P en queue de liste . L 1 2 3 4 nil Q P 0 nil API2 - LST«A» – p.31/42 Ajout en queue ➻ L désigne la tête de la liste et Q en désigne la queue. ➻ On se donne un élément pointé par P. ➻ Il s’agit de mettre P en queue de liste . L 1 2 3 4 nil Q P 0 nil . L 1 2 3 4 Q P 0 nil API2 - LST«A» – p.31/42 Ajout en queue procedure endAdd(var L:List; var Q:PtrNoeud; P:PtrNoeud); begin Q^.suiv := P ; Q := P ; end; // endAdd ➻ L est la tête de la liste ➻ Q est la queue de la liste ➻ P est le nouvel élément NB pour ne pas devoir parcourir à chaque fois la liste, on maintient un pointeur sur la queue de celle-ci. API2 - LST«A» – p.32/42 Liste : création ➻ On part d’une liste vide ➻ On fait des ajouts en tête procedure createListHead(out L: list) ; var P: PtrNoeud ; begin L := nil ; // liste vide getNoeud(P) ; // saisie d’un noeud while P^.info <> -1 do begin headAdd(L,P) ; getNoeud(P) ; end; //while end; // createListHead API2 - LST«A» – p.33/42 Liste : création ➻ On part d’une liste vide ➻ On fait des ajouts en queue procedure createListEnd(out L: list) ; var P,T: PtrNoeud ; begin L := nil ; // liste vide getNoeud(P) ; // saisie d’un noeud while P^.info <> -1 do begin if L = nil then begin L := P ; T := P ; end else endAdd(L,T,P) ; getNoeud(P) ; end; //while end; // createListEnd API2 - LST«A» – p.34/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : API2 - LST«A» – p.35/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : ➠ Ajouter un élément après un élément donné par son adresse API2 - LST«A» – p.35/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : ➠ Ajouter un élément après un élément donné par son adresse ➠ Supprimer l’élément suivant un élément donné par son adresse API2 - LST«A» – p.35/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : ➠ Ajouter un élément après un élément donné par son adresse ➠ Supprimer l’élément suivant un élément donné par son adresse ➠ Appliquer un traitement à tous les éléments d’une liste API2 - LST«A» – p.35/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : ➠ Ajouter un élément après un élément donné par son adresse ➠ Supprimer l’élément suivant un élément donné par son adresse ➠ Appliquer un traitement à tous les éléments d’une liste ➠ Chercher un élément dans une liste API2 - LST«A» – p.35/42 Liste : opérations ➻ Sur les listes, on peut être amené à faire les opérations suivantes : ➠ Ajouter un élément après un élément donné par son adresse ➠ Supprimer l’élément suivant un élément donné par son adresse ➠ Appliquer un traitement à tous les éléments d’une liste ➠ Chercher un élément dans une liste ➠ API2 - LST«A» – p.35/42 Ajouter un élément On veut insérer l’élément pointé par P, après l’élément pointé par Q dans la liste L. API2 - LST«A» – p.36/42 Ajouter un élément On veut insérer l’élément pointé par P, après l’élément pointé par Q dans la liste L. P 0 nil Q L 1 2 3 4 nil API2 - LST«A» – p.36/42 Ajouter un élément On veut insérer l’élément pointé par P, après l’élément pointé par Q dans la liste L. P 0 1 Q L 1 2 3 4 nil API2 - LST«A» – p.36/42 Ajouter un élément On veut insérer l’élément pointé par P, après l’élément pointé par Q dans la liste L. P Q L 1 2 0 1 2 3 4 nil API2 - LST«A» – p.36/42 Ajouter un élément On veut insérer l’élément pointé par P, après l’élément pointé par Q dans la liste L. P 0 Q L 1 2 1 2 3 4 nil Q L 1 2 3 0 4 nil API2 - LST«A» – p.36/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R ➻ On libère cette variable ensuite API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R ➻ On libère cette variable ensuite Q L 1 2 3 4 nil API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R ➻ On libère cette variable ensuite Q L 1 2 3 4 nil 1 R API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R ➻ On libère cette variable ensuite Q L 1 2 2 3 4 nil 1 R API2 - LST«A» – p.37/42 Supprimer un élément ➻ On veut supprimer l’élément suivant l’élément pointé par Q. ➻ On l’affecte à une variable temporaire R ➻ On libère cette variable ensuite Q L 1 2 2 3 4 nil 1 R Q L 1 2 4 nil API2 - LST«A» – p.37/42 Appliquer un traitement AppliquerTraitement(L): begin P := premier(L) ; while not estEnFin(P) do begin traiter(P) ; next(P) ; end; // while end; // AppliquerTraitement ➻ ➻ ➻ ➻ premier retourne la tête de liste estEnFin indique si la fin de liste est atteinte traiter applique un traitement au nœud P next avance le pointeur sur l’élément suivant API2 - LST«A» – p.38/42 Rechercher un élément recherche(P,L): begin Q := premier(L) ; trouve := false ; while not trouve and not estEnFin(Q) do begin if egal(Q,P) then trouve := true else Next(Q) ; end; // while retourner(trouve) end; // recherche API2 - LST«A» – p.39/42 Extension : bidirectionnelles ➻ Dans les listes simples, on ne peut pas revenir en arrière, car on n’a pas l’adresse du précédent. API2 - LST«A» – p.40/42 Extension : bidirectionnelles ➻ Dans les listes simples, on ne peut pas revenir en arrière, car on n’a pas l’adresse du précédent. ➻ Les listes bidirectionnelles n’ont pas cet inconvénient : chaque élément possède deux liens API2 - LST«A» – p.40/42 Extension : bidirectionnelles ➻ Dans les listes simples, on ne peut pas revenir en arrière, car on n’a pas l’adresse du précédent. ➻ Les listes bidirectionnelles n’ont pas cet inconvénient : chaque élément possède deux liens ➠ un vers son successeur API2 - LST«A» – p.40/42 Extension : bidirectionnelles ➻ Dans les listes simples, on ne peut pas revenir en arrière, car on n’a pas l’adresse du précédent. ➻ Les listes bidirectionnelles n’ont pas cet inconvénient : chaque élément possède deux liens ➠ un vers son successeur ➠ un vers son prédécesseur API2 - LST«A» – p.40/42 Extension : bidirectionnelles ➻ Dans les listes simples, on ne peut pas revenir en arrière, car on n’a pas l’adresse du précédent. ➻ Les listes bidirectionnelles n’ont pas cet inconvénient : chaque élément possède deux liens ➠ un vers son successeur ➠ un vers son prédécesseur L nil nil API2 - LST«A» – p.40/42 Exemple type PtrChainon = ^Chainon Chainon = record info : Integer ; // pred : PtrChainon ; suiv : PtrChainon ; end ; Pour supprimer l’élément pointé par Q : Q^.suiv^.pred := Q^.pred Q^.pred^.suiv := Q^.suiv dispose(Q) ; ; par exemple ; ; API2 - LST«A» – p.41/42 Extension : circulaires ➻ Ce sont des listes dans lesquelles le premier élément est le suivant du dernier. API2 - LST«A» – p.42/42 Extension : circulaires ➻ Ce sont des listes dans lesquelles le premier élément est le suivant du dernier. ➻ Elles peuvent être bidirectionnelles. API2 - LST«A» – p.42/42 Extension : circulaires ➻ Ce sont des listes dans lesquelles le premier élément est le suivant du dernier. ➻ Elles peuvent être bidirectionnelles. L API2 - LST«A» – p.42/42 Extension : circulaires ➻ Ce sont des listes dans lesquelles le premier élément est le suivant du dernier. ➻ Elles peuvent être bidirectionnelles. L API2 - LST«A» – p.42/42