1
INF145 : Onzième cours
PILES.CPP : Exemple d'une pile dynamique implantée avec une liste chaînée simple
#include <stdio.h>
#include <stdlib.h>
/*************************************************************/
typedef int t_objet; //type pour les données
typedef struct noeud * t_lien; //type-pointeur vers un autre noeud
struct noeud { //définition d’un struct noeud
t_objet x;
t_lien suivant;
};
typedef struct { //type structuré pour gérer la pile
int qte;
t_lien debut;
} pile;
/*************************************************************/
void creer_pile(pile *); //va créer une pile initialement vide
void push(t_objet, pile *); //ajouter un élément à la pile
t_objet pop(pile *); //enlever un élément de la pile
void affiche(pile); //affiche le contenu de la pile
/*************************************************************/
int main()
{ pile tete; //voici la pile!
int i;
creer_pile(&tete);
for (i=1; i<=5; ++i) { //boucle pour remplir la pile
push(10*i, &tete); //valeurs 10, 20, 30, 40, 50
affiche(tete);
}
system("pause");
for (i=1; i<=6; ++i) { //boucle pour vider la pile
printf("pop le %d = ", pop(&tete));
affiche(tete);
}
system("pause");
return 0;
}
/*************************************************************/
void creer_pile(pile *t) //cette fonction va créer une pile vide
{ t->qte = 0;
t->debut = NULL;
}
2
t_lien faire_noeud(t_objet x, t_lien suivant) //va créer un nouveau noeud
{ t_lien nd;
nd = (t_lien) malloc(sizeof(struct noeud));
if (nd == NULL) return NULL;
nd->x = x; //initialiser le champ de données
nd->suivant = suivant; //initialiser le lien au prochain noeud
return nd;
}
void push(t_objet x, pile *tete) //va ajouter un élément à la pile
{ t_lien pt;
pt = faire_noeud(x, tete->debut); //création d’un nouveau nœud..
if (pt == NULL) return;
tete->debut = pt; //..qui devient la nouvelle tête
tete->qte += 1;
}
t_objet pop(pile *tete) //va enlever un élément de la pile
{ t_lien pt = tete->debut;
t_objet valeur;
if (tete->qte == 0)
{ printf("Désolé, mais la pile est vide!");
return 0; //pile vide!!
}
else {
tete->debut = pt->suivant; //on déplace la tête au prochain noeud
tete->qte--;
valeur = pt->x; //prendre la valeur avant de détruire
free(pt);
return valeur;
}
}
void affiche(pile tete) //va afficher tous les nœuds de la pile
{ t_lien pt = tete.debut;
int i;
for (i=0; i < tete.qte; i++) { //boucle selon le nombre d’éléments
printf("%5d", pt->x);
pt = pt->suivant; //on passe au nœud suivant
}
printf("\n");
}
Traditionnellement, une liste chaînée sera gérée à l’intérieur d’un struct de gestion :
typedef struct {
t_lien tete; //pointeur vers le premier nœud de la liste
int nbr_element; //nombre d’éléments dans la liste
} t_liste;
Comme illustré dans l’exposé Powerpoint « Listes.pps ».
3
Gestion complète d’un type de donnée abstrait liste : liste_simple.cpp
//Le type des éléments dans la liste
typedef int t_element;
typedef struct noeud * ptr_noeud;
struct noeud {
t_element element; //l'élément contenu dans le noeud
ptr_noeud suivant; //pointe sur le suivant de la liste
};
typedef struct {
ptr_noeud debut; //pointe sur le début de la liste
ptr_noeud fin; //pointe sur la fin de la liste
unsigned int nbr_element; //nombre d'éléments en tout temps
} t_liste;
/********************************************************************/
/* DECLARATION DES FONCTIONS */
/********************************************************************/
//Retourne une liste initialisée et vide.
void creer_liste(t_liste *liste);
//On retourne s'il y a des éléments ou non.
int est_vide(const t_liste *liste);
//Retourne un pointeur sur le premier élément.
ptr_noeud get_tete(const t_liste *liste);
//Retourne le nombre d'éléments présentement dans la liste.
int get_nb_elements(const t_liste *liste);
//Retrouve un pointeur sur l'élément donné dans la liste.
//S'il n'y a pas d'éléments (debut==NULL) ou que l'élément donné
//n'est pas dans la liste, on retourne NULL.
ptr_noeud get_pos_element(t_liste *liste, t_element e);
//Les fonctions mutatrices d'insertion.
//Chaque fonction va retourner un pointeur sur le nouveau noeud.
ptr_noeud inserer_apres_pos(t_liste *liste, t_element element, ptr_noeud pc);
ptr_noeud inserer_fin(t_liste *liste, t_element element);
//Supprime la valeur à une position courante.
void supprimer(t_liste *liste, ptr_noeud pc);
//Libère l'espace associé à la liste et la remet à l'état vide.
//Il appelle free() pour chacun des éléments.
void liberer_liste(t_liste *liste);
//Cette fonction affiche le contenu de la liste.
void afficher_liste(const t_liste *liste);
4
/********************************************************************/
/* PROGRAMME PRINCIPAL */
/********************************************************************/
int main(void) {
t_liste une_liste; //la liste
unsigned long i;
ptr_noeud tmp;
creer_liste(&une_liste);
/* On ajoute dans la liste à la fin de celle-ci. */
printf("On ajoute dans la liste pour obtenir [0, 2, 4, 6, 8].\n");
for (i = 0; i < 5; ++i)
inserer_fin(&une_liste, 2 * i);
afficher_liste(&une_liste);
/* On ajoute au milieu de la liste. */
printf("On ajoute dans la liste pour obtenir [0, 1, 2, 3, 4, 5, 6, 7, 8].\n");
tmp = get_tete(&une_liste);
for (i = 0; i < 4; ++i) {
tmp = inserer_apres_pos(&une_liste, 2 * i + 1, tmp);
tmp = tmp->suivant;
}
afficher_liste(&une_liste);
/* On retire les valeurs paires de la liste. */
printf("On retire de la liste pour obtenir [1, 3, 5, 7].\n");
for (i = 0; i <= 10; i+=2) { //Retirer 0, 2, 4, 6, 8 et 10(?)
if (tmp = get_pos_element(&une_liste, i))
supprimer(&une_liste, tmp);
else
printf("Element %d pas dans la liste..\n", i);
}
afficher_liste(&une_liste);
/* Libérer la liste. */
liberer_liste(&une_liste);
system("pause");
return EXIT_SUCCESS;
}
/********************************************************************/
/* DEFINITION DES FONCTIONS */
/********************************************************************/
void afficher_liste(const t_liste *liste){
ptr_noeud tmp = get_tete(liste);
printf("Contenu de la liste : ");
//on imprime tous les éléments
while (tmp != NULL) {
printf("-->%i ", tmp->element);
tmp = tmp->suivant;
}
printf("= %lu elements\n\n", get_nb_elements(liste));
}
5
//Va créer un noeud contenant l'élément et un lien vers son suivant.
//Les allocations des noeuds sont dynamiques.
ptr_noeud creer_noeud(t_element element, ptr_noeud lien){
//Les noeuds sont dynamiques. On crée d'abord le noeud:
ptr_noeud nouv = (ptr_noeud) malloc(sizeof(struct noeud));
//On l'initialise avec les valeurs reçues
nouv->element = element;
nouv->suivant = lien;
return nouv;
}
//Retourne une liste initialisée et vide.
void creer_liste(t_liste *liste){
liste->debut = NULL;
liste->fin = NULL;
liste->nbr_element = 0;
}
//On retourne s'il y a des éléments ou non.
int est_vide(const t_liste *liste){
return liste->nbr_element == 0;
}
//Retourne un pointeur sur le premier élément.
ptr_noeud get_tete(const t_liste *liste){
return liste->debut;
}
//Retourne le nombre d'éléments présentement dans la liste.
int get_nb_elements(const t_liste *liste){
return liste->nbr_element;
}
//Retrouve l'élément fourni dans la liste et retourne un pointeur sur ce noeud.
//S'il n'y a pas d'éléments (debut==NULL) ou que l'élément envoyé
//n'est pas dans la liste, on retourne NULL.
ptr_noeud get_pos_element(t_liste *liste, t_element e){
int trouve = 0;
ptr_noeud pc = liste->debut;
while(pc != NULL && !trouve) {
if (pc->element != e)
pc = pc->suivant;
else
trouve = 1;
}
if(!trouve) return NULL;
else return pc;
}
//Insertion après la pc reçue. Retourne un pointeur sur le nouveau noeud.
ptr_noeud inserer_apres_pos(t_liste *liste, t_element element, ptr_noeud pc){
ptr_noeud nouv; //Sert à créer un nouveau noeud
1 / 10 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 !