Vous êtes sur la page 1sur 9

Introduction

Une liste linéaire (SDLL) est la représentation informatique d’un ensemble fini, de taille variable et
éventuellement nul d’éléments d’un type ordonné.

Listes linéaires
Les listes peuvent être homogènes ou hétérogènes. On s’intéresse aux listes homogènes de type T.

Une liste est une structure linéaire particulièrement souple, ses éléments peuvent être insérés ou
supprimés à n’importe quel endroit, contrairement aux structures de données pile et file (prochains
chapitres).
FAR AH FOU R AT I
Mathématiquement, une LL comporte des éléments cités dans un ordre donnée.
C O U R S AT EL I ER DE P R O G R A MMAT I O N 2
LSI1 - A U 2 0 2 3 -2 0 2 4
Par exemple ll1=(t1, t2, t3, t4, t5).
Me contacter : farah.fourati@issatso.u-sousse.tn

FARAH FOURATI - ISSATSO 2024

Aspects d’une SD Opérations sur la SD


En générale, les opérations applicables sur une structure de donnée sont divisées en trois catégories :
Structure de donnée (SD) :
qLes opérations de création (souvent une seule opération) : elles permettent de créer une structure SD.

Ø Aspect de mémorisation : elle stocke un ensemble d’éléments qLes opérations de consultation : elles permettent de fournir des renseignements sur l’état de la SD. Elles

laissent la SD inchangée.

Ø Aspect opérations : opérations applicables sur cette SD qLes opérations de modification : elles agissent sur la SD.

Dans la suite, on distingue : les opérations atomiques (ou élémentaires) et les opérations élaborés.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Opérations atomiques Opérations élaborés
§ creer_liste : permettant de créer une liste linéaire vide.
§inversion : permettant d’inverser une liste linéaire
§ liste_vide : permettant de voir si la liste linéaire est vide ou non
§ inserer ou opération d’adjonction : ll=(a, b, c, d) llinv=(d, c, b, a)
§ en tête : avant le premier §supprimer_tous : permet de supprimer tous les éléments d’une liste donnée.
§ en queue : après le dernier
§ quelque part au milieu
§concaténation : permet de concaténer deux listes données.
§ supprimer ou opération de suppression : ll1=(a, b, c, d) et ll2=(x, y, z, w, k)
§ premier élément
La concaténation de ll1 et ll2 dans l’ordre (ordre significatif) donne ll=(a, b, c, d, x, y, z, w, k)
§ dernier élément
§ quelque part au milieu
§ recherche : permettant de voir si un élément donnée appartient ou non à une liste linéaire
donnée. Le point de départ peut être fourni comme paramètre.
§ visiter : permettant de visiter tous les éléments de la SD LL en effectuant pour chaque
élément visité un traitement donnée (en paramètre). Le point de départ n’est pas forcément
le premier élément. Cette opération est connue sous le nom de traversée.
FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Représentation physique Représentation physique contigüe


Pour pouvoir matérialiser (concrétiser, réaliser ou implémenter) une SD on distingue deux types
de représentation physiques :
vReprésentation physique contigüe : les éléments d’une SD sont placés dans un espace
contigüe. Les éléments sont reliés d’une façon implicite. Idée : tableau.

vReprésentation physique chainée : les éléments d’une SD sont placés à des endroits
quelconques de la mémoire centrale mais chainés (ou reliés). Les éléments sont reliés d’une
façon explicite. Idée : pointeurs.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Représentation physique contigüe Représentation physique contigüe
recherche : recherche dans un tableau, on fait appel aux algorithmes connus
Illustration :
- soit recherche séquentielle (si la liste est non triée)
ll=(a, b, c, d) représentation abstraite - soit recherche dichotomique (si la liste est triée)

représentation concrète : adjonction :


elle exige des décalages à droite. Exemple : ajouter x après b.

- avant premier : décalage à droite de tous les éléments, elle dépend de la longueur de la liste
- après dernier : zéro décalage
- qlq part au milieu : ça nécessite des décalages à droite

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Représentation physique contigüe Traduction en C (rep. contigüe)


suppression : elle exige des décalages à gauche pour récupérer la position devenue disponible. Hypothèse :
Exemple : supprimer b
Type d’élément : entiers(int)
Solution 1 :
#define n 100
- premier : décalage à gauche de tous les éléments int cle [n] ;/*tableau pour mémoriser des entiers*/
- dernier : zéro décalage
int nb;
- qlq part au milieu : ça nécessite des décalages
La liste est caractérisée par une taille physique (n) et une taille logique (nb).
Critique : clé et nb sont étroitement (organiquement) liés, mais dans cette solution elles sont
visiter : balayer tous les éléments stockés dans la partie garnie.
dispersées (considérées comme variables indépendantes). D’où la solution suivante
En conclusion, la représentation physique contigue n’est pas recommandée par les deux
opérations d’adjonction et de suppression.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Traduction en C (rep. contigüe) Représentation physique chainée
Solution 2 : La représentation chainée comporte plusieurs nœuds. Chaque nœud regroupe les champs
suivants :
# define n 100
Le champ « cle » permet de mémoriser un élément de la SD.
struct liste
Le champ « suivant » permet de pointer sur l’élément suivant.
{
Pour repérer une SD selon une représentation physique chainée, on a besoin de pointeur(s)
int cle [n] ; d’entrée(s)
int nb;
} ;
struct liste l ;

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Représentation physique chainée Autres variantes de rep. chaînée


Variante 1 : Liste linéaire unidirectionnelle avec deux points d’entrée (premier et dernier) Variante 2: Liste linéaire unidirectionnelle avec un seul point d’entrée (premier)
cle suivant
cle suivant
a b c d
a b c d

premier dernier
premier

Dans cette représentation, le premier et le dernier élément sont favorisés : accès direct => c’est
la variante courante
L’adjonction dans une liste linéaire (LL) concrétisée à l’aide d’une représentation chaînée n’exige
pas de décalages contrairement à la représentation contiguë.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Autres variantes de rep. chaînée Autres variantes de rep. chaînée
Pour les deux variantes (1) et (2), la liste linéaire est unidirectionnelle. À partir d’un élément Variante 3: Liste linéaire bidirectionnelle avec deux points d’entrées
donné on peut passer à son successeur. Ceci est possible grâce au champ de chaînage suivant.
precedent cle suivant precedent cle suivant
Dans la variante (2), le premier élément est privilégié (accès direct)
Dans la variante (1) le premier et le dernier élément sont privilégiés (accès direct).
Mais on ne peut pas accéder au prédécesseur. dernier
premier

À partir d’un élément donné, on peut passer soit à son successeur soit à son prédécesseur.
Le successeur du dernier élément n’existe pas. Et également, le prédécesseur du premier
élément n’existe pas.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Autres variantes de rep. chaînée Traduction en C (rep. chaînée)


Variante 4: Liste linéaire circulaire ou en anneau Hypothèse :
Type d’élément : entiers(int)
cle suivant Point Pour pouvoir regrouper les deux champs clé et suivant, on fait appel au type struct fourni par C.
d’entrée
Variante 2 : Liste linéaire unidirectionnelle avec un point d’entrée (premier)
struct noeud{ noeud
cle suivant
int cle; premier
struct noeud *suivant;
Les notions de premier et dernier disparaissent ou n’ont pas de sens Un anneau est doté };
uniquement d’un point d’entrée quelconque.
struct noeud *premier;
Une liste circulaire peut être également bidirectionnelle.

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Traduction en C (rep. chaînée) Notez que:
Hypothèse :
Type d’élément : entiers(int) Variables en C : Résidence : Durée de vie:
Variante 1 : Liste linéaire unidirectionnelle avec deux points d’entrée (premier et dernier) variable globale dans une zone mémoire appelée segment de à celle du programme
donnée
struct noeud{
variable locale dans une zone mémoire appelée pile à celle de son sous-programme
int cle;
liste variable dynamique dans une zone mémoire appelée Heap (ou tas) sa durée de vie est explicite :
struct noeud *suivant; noeud
cle suivant création è malloc
}; premier
suppression è free

struct liste{
struct noeud *premier; dernier
struct noeud *dernier;
};

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Explications Exercice corrigé


Programmer en C quelques opérations fondamentales applicables sur la SDLL :
Les éléments d’une SD matérialisée par une représentation chainée résident dans une zone
mémoire appelée Heap (ou tas). ØOpération de création:
• Sous forme de procédure: void creer_liste(struct liste *ll)
Les éléments formant la SDLL sont créés grâce à ajouter qui fait appel à malloc üSous forme de fonction (solution retenue): struct liste *creer_liste(void)
Les éléments de la SDLL peuvent être supprimés grâce à supprimer qui fait appel à free. ØOpération de vacuité d’une liste: unsigned liste_vide(struct liste *ll)

Les variables stockés dans le Heap sont appelés variables dynamiques ØOpérations d’adjonction ou d’insertion
üAjouter avant le premier: void ajouter_premier(int info, struct liste *ll)
Un pointeur en C sert souvent à repérer une variable dynamique. (premier est une variable de üAjouter après le dernier: void ajouter_dernier(int info, struct liste *ll)
type pointeur) üAjouter quelque part au milieu
En C : premier=NULL ; /*NULL est une macro est la valeur d'un pointeur nulle part, il s’agit d’une ü Après un élément référencé : void ajouter_apres(int info, struct noeud *p)
constante symbolique appartenant aux bibliothèques stdio.h, stdlib.h, alloc.h*/ ü Avant un élément référencé : void ajouter_avant(int info, struct noeud *p)

ØOpérations de suppression
• Supprimer premier : void supprimer_premier(struct liste *ll)

ØOpération de recherche : struct noeud * recherche(int info, struct noeud *p)


FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024
Exercice corrigé (suite) Utilisation de la procédure parcours (1):
ØOpération de parcours (traversée) 1- Afficher chaque élément visité.
Indication : rappel sur les paramètres en c void afficher(struct noeud *p){
qParamètre non fonctionnel : traduit par des variables, il mémorise une valeur (ordinaire ou printf("%d\n",p->cle);
adresse). Exemple : struct noeud * recherche(int info, struct noeud *p) ;
}
qParamètre fonctionnel : traduit par des pointeurs sur des sous-programmes, il mémorise un
comportement (ou un traitement). Un sous-programme admettant des paramètres fonctionnels est struct noeud *point_de_depart; //à initialiser
dit sous-programme d’ordre supérieur.
parcours(point_de_depart,afficher);
void parcours(struct noeud *p, void (*oper)(struct noeud *));
En c, le nom d’un sous-programme est considéré comme un pointeur. Toute référence à (*oper)
p: paramètre non fonctionnel qui traduit le point de départ.
au sein de la P.E du sous-programme parcours est une référence au paramètre effectif
oper: un pointeur qui pointe sur une procédure exigeant un pointeur sur struct nœud. correspondant : c’est le principe d’indirection.
A ne pas confondre! void *oper (struct noeud *) est une fonction exigeant un paramètre de type struct
nœud* et rendant n’importe quoi ( void * est un pointeur générique).

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Utilisation de la procédure parcours (2): Rep contiguë/ Rep chaînée


Traitement incrémenter chaque élément visité : Problème : Trouver une représentation physique permettant de mémoriser d’une façon efficace
des matrices creuses, sachant qu’une matrice creuse est une matrice comportant un nombre
Le traitement consiste à incrémenter tous les éléments visités. élevé d’éléments nuls. Un tel nombre tend vers n*n.
void incrementer(struct noeud *p){ La représentation souhaitée doit stocker uniquement les éléments non nuls.
p->cle=p->cle+1; Exemple :
}
struct noeud *point_de_depart; //à initialiser
parcours(point_de_depart, incrementer);

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Solution 1 Solution 2: Réduire la complexité spatiale?
/*représentation usuelle*/ Idée: éviter de stocker les éléments nuls.
#define n 100 qChoix 1:
ØAccès rapide ou direct sur la ligne
float m [n] [n];
ØAccès moins rapide ou séquentiel sur la colonne
Complexité spatiale : O(n2)
q Choix 2:
Complexité temporelle : ØAccès rapide ou direct sur la colonne
ØAccès moins rapide ou séquentiel sur la ligne
m[i][j]=x; en O(1)
qChoix 3:
x=m[i][j]; en O(1)
ØAccès séquentiel sur la ligne
ØAccès séquentiel sur la colonne

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024

Solution choix 1: accès directe sur la ligne Exemple :


La colonne appartenant à une ligne i est obtenu par recherche séquentielle au sein de la liste ligne[i]
On a intérêt à trier les listes sur le champ colonne.
Traduction en c
#define n 100
struct element{
unsigned col;
float cle;
struct element * suivant;
};
struct element* ligne[n];

FARAH FOURATI - ISSATSO 2024 FARAH FOURATI - ISSATSO 2024


Opérations applicables
Une matrice creuse peut être assimilée à une SD dotés des opérations suivantes :
- Création d’une matrice creuse vide : tous les éléments sont à zéro.
- Accès à un élément identifié par le couple (ligne :i, colonne : j)
- Modification d’un élément donnée

FARAH FOURATI - ISSATSO 2024

Vous aimerez peut-être aussi