La pile est une structure de données, qui permet
de stocker les données dans l'ordre LIFO (Last In First Out) - en français Dernier
Entré Premier Sorti).
L'insertion se faisant toujours au début de la liste, le 1er élément de la
liste sera le dernier élément saisi, donc sa position est en haut de la pile.
Ce qui nous intéresse c'est que le dernier élément entré, sera le 1er élément
récupéré.

Pour
définir un élément de la pile le type struct
sera utilisé.
L'élément de la pile contiendra un champ donnee et un
pointeur suivant.
Le pointeur suivant doit être du même type que l'élément, sinon il ne pourra
pas pointer vers l'élément.
Le pointeur suivant permettra l'accès vers le prochain élément.
typedef struct ElementListe {
char *donnee; struct ElementListe *suivant;}Element;
Pour
permettre les opérations sur la pile, nous allons sauvegarder certains éléments
:
Le
1er élément, qui se trouve en haut de la pile, nous permettra de réaliser
l'opération de récupération des données situées en haut de la pile.
Pour réaliser cela, une autre structure sera utilisée (ce n'est pas
obligatoire, des variables peuvent être utilisées).
Voici sa composition :
typedef struct ListeRepere{
Element *debut; int taille;} Pile;
Le pointeur debut contiendra l'adresse du premier
élément de la liste.
La variable taille contient le nombre d'éléments.
Observation :
Quelque soit la position dans la liste, le pointeur debut
pointe toujours vers le 1er élément, qui sera en haut de la pile.
Le champ taille contiendra le nombre d'éléments de la pile, quelque soit
l'opération effectuée sur la pile.
Prototype
de la fonction :
void initialisation (Pile *tas);
Cette
opération doit être faite avant toute autre opération sur la pile.
Elle initialise le pointeur debut avec le pointeur
NULL, et la taille avec la valeur 0.
La fonction
void initialisation (Pile * tas){
tas->debut = NULL; tas->taille = 0;}
Voici
l'algorithme d'insertion et de sauvegarde des éléments :
Prototype
de la fonction :
int empiler (Pile *tas, char *donnee);
La 1ère image montre le début de l'insertion, donc
la liste a la taille 1 après l'insertion. La
caractéristique de la pile n'est pas très bien mise en évidence avec un seul
élément, puisque c'est le seul à récupérer.

En revanche la 2ème image nous permet d'observer
le comportement de la pile.
La chose qu'il faut retenir, c'est que l'insertion se fait toujours en haut de
la pile (au début de la liste).

La fonction
/* empiler (ajouter) un élément dans la pile */int empiler (Pile * tas, char *donnee){
Element *nouveau_element; if ((nouveau_element = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nouveau_element->donnee = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nouveau_element->donnee, donnee); nouveau_element->suivant = tas->debut; tas->debut = nouveau_element; tas->taille++;}
Pour
supprimer (ôter ou dépiler) l'élément de la pile, il faut tout simplement
supprimer l'élément vers lequel pointe le pointeur debut.
Cette opération ne permet pas de récupérer la donnée en haut de la pile, mais
seulement de la supprimer.
Prototype de la fonction :
int depiler (Pile *tas);
La
fonction renvoie -1 en cas d'échec sinon elle renvoie 0.
Les étapes :

La fonction
int depiler (Pile * tas){
Element *supp_element;
if (tas->taille == 0) return -1; supp_element = tas->debut;tas->debut = tas->debut->suivant;
free (supp_element->donnee);
free (supp_element);tas->taille--;
return 0;}
Pour
afficher la pile entière, il faut se positionner au début de la pile (le
pointeur debut le permettra).
Ensuite, en utilisant le pointeur suivant de chaque élément, la pile est
parcourue du 1er vers le dernier élément.
La condition d'arrêt est donnée par la taille de la pile.
La fonction
/* affichage de la pile */void affiche (Pile * tas){
Element *courant;
int i; courant = tas->debut; for(i=0;i<tas->taille;++i){printf("\t\t%s\n", courant->donnee);
courant = courant->suivant; }}
Pour
récupérer la donnée en haut de la pile sans la supprimer, j'ai utilisé une
macro. La macro lit les données en haut de la pile en utilisant le pointeur debut.
#define pile_donnee(tas) tas->debut->donnee
/*********************\ * pile.h *\*********************/typedef struct ElementListe{
char *donnee; struct ElementListe *suivant;} Element; typedef struct ListeRepere{
Element *debut;int taille;
} Pile; /* initialisation */void initialisation (Pile *tas);
/* EMPILER*/int empiler (Pile *tas, char *donnee);
/* DEPILER*/int depiler (Pile *tas);
/* Affichage de élément en haut de la pile (LastInFirstOut) */#define pile_donnee(tas) tas->debut->donnee /* Affiche la pile */void affiche (Pile *tas);
/***********************\ * pile_function.h *\***********************/ void initialisation (Pile * tas){
tas->debut = NULL; tas->taille = 0;} /* empiler (ajouter) un élément dans la pile */int empiler (Pile * tas, char *donnee){
Element *nouveau_element; if ((nouveau_element = (Element *) malloc (sizeof (Element))) == NULL) return -1; if ((nouveau_element->donnee = (char *) malloc (50 * sizeof (char))) == NULL) return -1; strcpy (nouveau_element->donnee, donnee); nouveau_element->suivant = tas->debut; tas->debut = nouveau_element; tas->taille++;} /* depiler (supprimer un élément de la pile */int depiler (Pile * tas){
Element *supp_element; if (tas->taille == 0) return -1; supp_element = tas->debut; tas->debut = tas->debut->suivant;free (supp_element->donnee);
free (supp_element);tas->taille--;
return 0;} /* affichage de la pile */void affiche (Pile * tas){
Element *courant;int i;
courant = tas->debut; for(i=0;i<tas->taille;++i){printf("\t\t%s\n", courant->donnee);
courant = courant->suivant; }}
/*********************\ * pile.c *
\*********************/#include<stdio.h>#include<stdlib.h>#include<string.h>#include "pile.h"#include "pile_function.h" int main ()
{ Pile *tas; char *nom;if ((tas = (Pile *) malloc (sizeof (Pile))) == NULL)
return -1; if ((nom = (char *) malloc (50 * sizeof (char))) == NULL)return -1;
initialisation (tas); printf ("Entrez un mot : "); scanf ("%s", nom); empiler (tas, nom); printf ("La pile (%d éléments): \n",tas->taille); printf("\n********** Haut de la PILE **********\n"); affiche(tas); printf("__________ Bas de la PILE __________\n\n"); printf ("Entrez un mot : "); scanf ("%s", nom); empiler (tas, nom); printf ("La pile (%d éléments): \n",tas->taille); printf("\n********** Haut de la PILE **********\n"); affiche(tas); printf("__________ Bas de la PILE __________\n\n"); printf ("Entrez un mot : "); scanf ("%s", nom); empiler (tas, nom); printf ("La pile (%d éléments): \n",tas->taille); printf("\n********** Haut de la PILE **********\n"); affiche(tas); printf("__________ Bas de la PILE __________\n\n"); printf ("\nLe dernier entré (LastInFirstOut) [ %s ] sera supprimé", pile_donnee(tas)); printf ("\nLe dernier entré est supprime\n"); depiler (tas); /* suppression de dernier element entre */ printf ("La pile (%d éléments): \n",tas->taille); printf("\n********** Haut de la PILE **********\n"); affiche(tas); printf("__________ Bas de la PILE __________\n\n"); return 0;
}