1
INF145 : Dixme cours
Les Structures de Données :
- Définition :
o Organisation de l’information permettant d’améliorer l’efficacité d’un
algorithme. Une telle structure peut contenir des informations redondantes
- Caractéristiques les plus courantes :
o Vitesse d’ajout, de retrait et de consultation ;
o Espace mémoire occupée (y a t’il des tadonnées, est-ce que si la
structure est vide celle-ci occupe quand même beaucoup de mémoire ?) ;
o Flexibilité (la taille est-elle limitée par une constante à la compilation ?).
Les Listes Chaînées Simples :
- Définition : Structure de données les objets sont arrangés de façon linéaire.
À la différence d’un tableau, où l’ordre linéaire est déterminé par l’indice des
éléments, l’ordre dans une liste chaînée est terminé par un pointeur dans
chacun des objets. Les listes chaînées fournissent une représentation simple et
flexible pour implanter des ensembles dynamiques et supportent (bien que pas
toujours de façon efficace) les opérations associées à un ensemble dynamique ;
Consultez l’exposé powerpoint « Listes.pps ».
- Implantation :
Un « nœud » dans une liste chaînée est une structure (type struct) qui
contient un pointeur à une autre structure du même type, et ainsi de suite :
struct noeud {
int data; /* Champ de données */
struct noeud * suivant;
};
Ou encore :
typedef struct noeud T_noeud;
struct noeud {
int data; /* Champ de données… */
T_noeud * suivant; /* Pointeur */
};
Déclaration de 3 nœuds de type « T_noeud » :
T_noeud a, b, c;
2
Initialisation des données (sans faire les liens!) :
a.data = 1;
b.data = 2;
c.data = 3;
a.suivant = b.suivant = c.suivant = NULL;
Résultat : a b c
1
NULL
2
NULL
3
NULL
La valeur NULL sera la valeur spéciale (=0) qui indiquera la fin d’une liste chaînée.
Pour faire la liaison des 3 nœuds ensemble :
a.suivant = &b;
b.suivant = &c;
Résultat : a b c
1
2
3
NULL
Quelle est la valeur de : a.data ?
a.suivant->data ?
a.suivant->suivant->data ?
Déclarations pour former une liste chaînée simple (ordonnée) :
NOTE : Il est préférable d’utiliser typedef pour la déclaration du type des données.
typedef int T_objet;
typedef struct noeud * T_lien;
struct noeud {
T_objet data; /* champ des données */
T_lien suivant; /* pointeur au nœud suivant */
};
Le type « struct noeud » sera employé pour faire l’allocation dynamique (avec malloc)
de la liste un nœud à la fois. Pour créer une liste vide, nous avons seulement besoin
d’un seul pointeur :
T_lien tete = NULL;
Pour créer le premier nœud de la liste :
tete = (T_lien) malloc(sizeof(struct noeud)); //1 noeud
tete->data = 2;
tete->suivant = NULL;
Résultat : tete
2
NULL
3
On ajoute un 2ième nœud (à la fin de la liste) :
T_lien tempo = (T_lien) malloc(sizeof(struct noeud));
tempo->data = 4;
tempo->suivant = NULL;
tete->suivant = tempo; //faire le lien avec la tête
Résultat : tete
(tempo)
Ajouter un nœud au début de la liste :
Étapes :
1. Créer un nouveau nœud avec « malloc ». Variable « tempo » pointe à ce
nouveau nœud ;
2. Remplir « *tempo » avec les nouvelles données (dans : tempo->data ) ;
3. Initialiser « tempo->suivant » pour que ce pointeur pointe à la « tete » ;
4. Faire : « tete = tempo; » pour déplacer la tête de la liste.
void inserer_au_debut(T_lien *tete, T_objet x)
{ T_lien tempo;
tempo = (T_lien) malloc(sizeof(struct noeud));
if (tempo == NULL) return; //valider l'allocation dynamique
tempo->data = x;
tempo->suivant = *tete;
*tete = tempo;
}
appel de cette fonction : inserer_au_debut(&tete, 1);
Résultat : tete
(tempo)
Insérer un nœud dans la liste (au milieu) :
Étapes : insertion après le nœud « Ici ».
1. Localiser l’endroit où on veut insérer le nœud (positionner pointeur « Ici ») ;
2. Créer le nouveau noeud « tempo » avec « malloc » et remplir son contenu ;
3. Initialiser « tempo->suivant = ici->suivant; » ;
4. Initialiser « ici->suivant = tempo; ».
ATTENTION : ne PAS faire l’étape 4 avant l’étape 3 !!!
2
4
NULL
1
2
4
NULL
4
void inserer(T_lien *tete, T_objet x)
{ T_lien ici, next, tempo;
tempo = (T_lien) malloc(sizeof(struct noeud));
if (tempo == NULL) return; //valider l'allocation dynamique
tempo->data = x;
ici = NULL;
next = *tete;
/* Boucle pour localiser l’endroit où « x » sera insérée */
while ((next != NULL) && (next->data < x)) {
ici = next;
next = next->suivant;
}
if (ici == NULL) { //ajouter la valeur «x» au début!
tempo->suivant = *tete;
*tete = tempo;
}
else { //insertion du nouveau nœud avec valeur x
tempo->suivant = ici->suivant;
ici->suivant = tempo;
}
}
appel de cette fonction : inserer(&tete, 3);
Résultat : tete
(ici) (tempo) (next)
Retirer un nœud de la liste :
Nous aurons besoin de 2 pointeurs : « ici » et « avant ».
Étapes : retrait du nœud qui contient « x ».
1. Faire : ici = *tete; avant = NULL;
2. Tant que (ici fin de la liste) ET ( *ici ne contient pas « x »)
Faire : avant = ici; ici = ici->suivant; //aller à droite
3. Si (ici NULL) // l’élément « x » à été trouvé
Si (ici == *tete), *tete = ici->suivant;
Sinon, avant->suivant = ici->suivant;
4. Libérer la mémoire du nœud éliminé : free(ici);
1
2
3
4
NULL
5
Rechercher un élément dans la liste :
Étapes : recherche de la valeur « x ».
1. Initialiser : tempo = tete;
2. Tant que (tempo fin de la liste) ET ( *tempo ne contient pas « x »)
Faire : tempo = tempo->suivant;
3. Si (tempo == NULL) //fin de la liste!
L’élément n’est pas dans la liste, on renvoie NULL
Sinon, on a trouvé l’élément « x », on renvoie un pointeur à ce nœud.
En C, sous forme de fonction :
T_lien trouver_element(T_lien tete, T_objet x){
T_lien tempo = tete;
while ((tempo != NULL) && (tempo->data != x))
tempo = tempo->suivant;
return tempo;
}
Exemple d’appel de la fonction :
T_lien ici = trouver_element(tete, 3);
if (ici != NULL) { . . . }
Intro_Liste.CPP : Exemple de gestion d'une liste chaînée simple
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
/********************************************************************/
/* DEFINITION DES TYPES */
/********************************************************************/
typedef int T_objet;
typedef struct noeud * T_lien;
struct noeud {
T_objet data;
T_lien suivant;
};
/********************************************************************/
/* Déclarations des fonctions de gestion de liste */
/********************************************************************/
void ajouter(T_lien *, T_lien *, T_objet);
int retirer_le_i(const T_lien *, int, T_objet *);
void retirer_du_debut(T_lien *);
1 / 11 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !