Piles et Files

Exercice 1 : (Création d’une pile et ses fonctions)

On vous demande d’implémenter (par liste), une Pile permettant de représenter des piles d’entiers. Pour cela vous développerez les fonctions et opérateurs de base permettant de manipuler les piles, à savoir:

  • La fonction permettant de créer une pile vide.
  • bool vide() : teste de vacuité.
  • int hauteur() : retourne la hauteur de la pile.
  • void empiler(int n) : fonction permettant d’empiler un entier au sommet de la pile.
  • void depiler() : enlève l’élément au sommet de la pile.
  • void remplacer(int n) : remplace le sommet de la pile par n.
  • int sommet() : retourne l’élément au sommet de la pile.

Solution :

#include <iostream>

using  namespace  std  ;

struct  elemenet
{
    int                data  ;
    struct elemenet *  next  ;
};

typedef  struct elemenet Element  ;
typedef  Element *       Stack    ;

Stack  create_stack()
{
    return  NULL  ;
}

bool  is_empty_stack(Stack stk)
{
    if(stk == NULL)
        return  true  ;
    else
        return  false ;
}

int  deapth_stack(Stack stk)
{
    Stack  ptr    =  stk  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Stack  push_stack(Stack stk, int val)
{
    Stack  ptr  =  new  Element  ;
    ptr->data   =  val  ;

    ptr->next  =  stk  ;
    stk        =  ptr  ;

    return  stk  ;
}

Stack  pop_stack(Stack stk, int &val)
{
    if(!is_empty_stack(stk))
    {
        Stack  ptr  =  stk  ;

        val  =  stk->data  ;
        stk  =  stk->next  ;
        delete  ptr        ;

        return  stk  ;
    }
    else
    {
        cout  <<  "Error, the stack is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  top_stack(Stack stk)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  0  ;
    }

    return  stk->data  ;
}

Stack  replace_top_stack(Stack stk, int val)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  NULL  ;
    }

    stk->data  =  val  ;

    return  stk  ;
}

void  display_stack(Stack stk)
{
    Stack  ptr    =  stk  ;

    if(is_empty_stack(stk))
    {
        cout  <<  "Stack is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

int  main()
{
    Stack  stk  =  create_stack()  ;

    display_stack(stk)  ;

    stk  =  push_stack(stk, 1)  ;
    stk  =  push_stack(stk, 2)  ;
    stk  =  push_stack(stk, 3)  ;

    display_stack(stk)  ;

    cout  <<  "The top of the stack is  : "  <<  top_stack(stk)  <<  endl  ;

    stk  =  replace_top_stack(stk, 4)  ;

    display_stack(stk)  ;

    cout  <<  "The depth of the stack is  : "  <<  deapth_stack(stk)  <<  endl  ;

    int  val  ;

    stk  =  pop_stack(stk, val)  ;
    cout  <<  "The value popped from the stack is  : "  <<  val  <<  endl  ;
    display_stack(stk)  ;

    stk  =  pop_stack(stk, val)  ;
    cout  <<  "The value popped from the stack is  : "  <<  val  <<  endl  ;
    display_stack(stk)  ;

    stk  =  pop_stack(stk, val)  ;
    cout  <<  "The value popped from the stack is  : "  <<  val  <<  endl  ;
    display_stack(stk)  ;

    return  0  ;
}

Exercice 2 : (Création d’une file et ses fonctions)

On vous demande d’implémenter (dynamiquement : par liste) une File permettant de représenter des files d’entiers. Pour cela vous développerez les fonctions et opérateurs de base permettant de manipuler les files, à savoir :

  • La structure permettant de créer une file vide.
  • bool vide() : teste de vacuité.
  • int longueur() : retourne la longueur de la file.
  • void adjq(int n) : adjonction en queue d’un entier n. // Emfiler
  • void supt() : suppression de l’élément en tête de la file. // Defiler
  • int tete() : retourne l’élément en tête de la file.

Solution :

#include <iostream>

using  namespace  std  ;

struct  elemenet
{
    int                data  ;
    struct elemenet *  next  ;
};

typedef  struct elemenet Element  ;
typedef  Element *       Queue    ;

Queue  create_queue()
{
    return  NULL  ;
}

bool  is_empty_queue(Queue que)
{
    if(que == NULL)
        return  true  ;
    else
        return  false ;
}

int  deapth_queue(Queue que)
{
    Queue  ptr    =  que  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Queue  enqueue(Queue que, int val)
{
    Queue  elm  =  new  Element  ;
    elm->data   =  val   ;
    elm->next   =  NULL  ;

    if(is_empty_queue(que))
    {
        que  =  elm  ;
        return  que  ;
    }

    Queue  ptr  =  que  ;

    while(ptr->next != NULL)
        ptr  =  ptr->next  ;

    ptr->next  =  elm  ;

    return  que  ;
}

Queue  dequeue(Queue que, int &val)
{
    if(!is_empty_queue(que))
    {
        Queue  ptr  =  que  ;

        val  =  que->data  ;
        que  =  que->next  ;
        delete  ptr        ;

        return  que  ;
    }
    else
    {
        cout  <<  "Error, the queue is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  front_queue(Queue que)
{
    if(is_empty_queue(que))
    {
        cout  <<  "Error, Queue is empty."  <<  endl  ;
        return  0  ;
    }

    return  que->data  ;
}

int  rear_queue(Queue que)
{
    if(is_empty_queue(que))
    {
        cout  <<  "Error, Queue is empty."  <<  endl  ;
        return  0  ;
    }

    Queue  ptr  =  que  ;

    while(ptr->next != NULL)
        ptr  =  ptr->next  ;

    return  ptr->data  ;
}

void  display_queue(Queue que)
{
    Queue  ptr    =  que  ;

    if(is_empty_queue(que))
    {
        cout  <<  "Queue is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

int  main()
{
    Queue  que  =  create_queue()  ;

    display_queue(que)  ;

    que  =  enqueue(que, 1)  ;
    que  =  enqueue(que, 2)  ;
    que  =  enqueue(que, 3)  ;

    display_queue(que)  ;

    cout  <<  "The front of the queue is  : "  <<  front_queue(que)  <<  endl  ;

    cout  <<  "The rear of the queue is  : "   <<  rear_queue(que)   <<  endl  ;


    cout  <<  "The depth of the queue is  : "  <<  deapth_queue(que)  <<  endl  ;

    int  val  ;

    que  =  dequeue(que, val)  ;
    cout  <<  "The value dequeued from the queue is  : "  <<  val  <<  endl  ;
    display_queue(que)  ;

    que  =  dequeue(que, val)  ;
    cout  <<  "The value dequeued from the queue is  : "  <<  val  <<  endl  ;
    display_queue(que)  ;

    que  =  dequeue(que, val)  ;
    cout  <<  "The value dequeued from the queue is  : "  <<  val  <<  endl  ;
    display_queue(que)  ;

    return  0  ;
}

Exercice 3 : (Inverser une pile et une file en préservant les originales)

Concevoir deux algorithmes, qui créent respectivement :

  • la file inverse d’une file .
  • la pile inverse d’une pile.

Ces deux algorithmes doivent restituer leur entrée inchangée.

Solution :

#include <iostream>

using  namespace  std  ;

struct  elemenet
{
    int                data  ;
    struct elemenet *  next  ;
};

typedef  struct elemenet Element  ;
typedef  Element *       Stack    ;
typedef  Element *       Queue    ;

Stack  create_stack()
{
    return  NULL  ;
}

bool  is_empty_stack(Stack stk)
{
    if(stk == NULL)
        return  true  ;
    else
        return  false ;
}

int  depth_stack(Stack stk)
{
    Stack  ptr    =  stk  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Stack  push(Stack stk, int val)
{
    Stack  ptr  =  new  Element  ;
    ptr->data   =  val  ;

    ptr->next  =  stk  ;
    stk        =  ptr  ;

    return  stk  ;
}

Stack  pop(Stack stk, int &val)
{
    if(!is_empty_stack(stk))
    {
        Stack  ptr  =  stk  ;

        val  =  stk->data  ;
        stk  =  stk->next  ;
        delete  ptr        ;

        return  stk  ;
    }
    else
    {
        cout  <<  "Error, the stack is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  top_stack(Stack stk)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  0  ;
    }

    return  stk->data  ;
}

Stack  replace_top_stack(Stack stk, int val)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  NULL  ;
    }

    stk->data  =  val  ;

    return  stk  ;
}

void  display_stack(Stack stk)
{
    Stack  ptr    =  stk  ;

    if(is_empty_stack(stk))
    {
        cout  <<  "Stack is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

Queue  create_queue()
{
    return  NULL  ;
}

bool  is_empty_queue(Queue que)
{
    if(que == NULL)
        return  true  ;
    else
        return  false ;
}

int  length_queue(Queue que)
{
    Queue  ptr    =  que  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Queue  enqueue(Queue que, int val)
{
    Queue  elm  =  new  Element  ;
    elm->data   =  val   ;
    elm->next   =  NULL  ;

    if(is_empty_queue(que))
    {
        que  =  elm  ;
        return  que  ;
    }

    Queue  ptr  =  que  ;

    while(ptr->next != NULL)
        ptr  =  ptr->next  ;

    ptr->next  =  elm  ;

    return  que  ;
}

Queue  dequeue(Queue que, int &val)
{
    if(!is_empty_queue(que))
    {
        Queue  ptr  =  que  ;

        val  =  que->data  ;
        que  =  que->next  ;
        delete  ptr        ;

        return  que  ;
    }
    else
    {
        cout  <<  "Error, the queue is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  tail_queue(Queue que)
{
    if(is_empty_queue(que))
    {
        cout  <<  "Error, Queue is empty."  <<  endl  ;
        return  0  ;
    }

    return  que->data  ;
}

int  head_queue(Queue que)
{
    if(is_empty_queue(que))
    {
        cout  <<  "Error, Queue is empty."  <<  endl  ;
        return  0  ;
    }

    Queue  ptr  =  que  ;

    while(ptr->next != NULL)
        ptr  =  ptr->next  ;

    return  ptr->data  ;
}

void  display_queue(Queue que)
{
    Queue  ptr    =  que  ;

    if(is_empty_queue(que))
    {
        cout  <<  "Queue is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

Queue  reverse_queue(Queue &que)
{
    Queue  rst  =  create_queue()  ;
    Stack  stk  =  create_stack()  ;

            int  val  ;

    for(int i = 0 ; i < length_queue(que) ; i++)
    {
        que  =  dequeue(que, val)  ;
        que  =  enqueue(que, val)  ;
        stk  =  push(stk, val)     ;
    }

    while(!is_empty_stack(stk))
    {
        stk  =  pop(stk, val)      ;
        rst  =  enqueue(rst, val)  ;
    }

    return  rst  ;
}

Stack  reverse_stack(Stack &stk)
{
    Stack  rst  =  create_stack()  ;
    Stack  tmp  =  create_stack()  ;

    int  val  ;

    while(!is_empty_stack(stk))
    {
        stk  =  pop(stk, val)   ;

        rst  =  push(rst, val)  ;
        tmp  =  push(tmp, val)  ;
    }

    while(!is_empty_stack(tmp))
    {
        tmp  =  pop(tmp, val)   ;
        stk  =  push(stk, val)  ;
    }

    return  rst  ;
}

int  main()
{
    Queue  que  =  create_queue()  ;

    que  =  enqueue(que, 1)  ;
    que  =  enqueue(que, 2)  ;
    que  =  enqueue(que, 3)  ;

    display_queue(que)  ;

    Queue  q2  =  reverse_queue(que)  ;
    display_queue(q2)  ;

    Stack  stk  =  create_stack()  ;

    stk  =  push(stk, 1)  ;
    stk  =  push(stk, 2)  ;
    stk  =  push(stk, 3)  ;

    display_stack(stk)  ;

    Stack  s2  =  reverse_stack(stk)  ;

    display_stack(s2)  ;

    return  0  ;
}

Exercice 4 : (Inverser une pile)

Écrire un algorithme utilisant une pile (implémentée sous forme de liste chaînée) qui affiche une liste chaînée d’entiers à l’envers.

Solution :

#include <iostream>

using  namespace  std  ;

struct  elemenet
{
    int                data  ;
    struct elemenet *  next  ;
};

typedef  struct elemenet Element  ;
typedef  Element *       Stack    ;

Stack  create_stack()
{
    return  NULL  ;
}

bool  is_empty_stack(Stack stk)
{
    if(stk == NULL)
        return  true  ;
    else
        return  false ;
}

int  depth_stack(Stack stk)
{
    Stack  ptr    =  stk  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Stack  push(Stack stk, int val)
{
    Stack  ptr  =  new  Element  ;
    ptr->data   =  val  ;

    ptr->next  =  stk  ;
    stk        =  ptr  ;

    return  stk  ;
}

Stack  pop(Stack stk, int &val)
{
    if(!is_empty_stack(stk))
    {
        Stack  ptr  =  stk  ;

        val  =  stk->data  ;
        stk  =  stk->next  ;
        delete  ptr        ;

        return  stk  ;
    }
    else
    {
        cout  <<  "Error, the stack is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  top_stack(Stack stk)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  0  ;
    }

    return  stk->data  ;
}

Stack  replace_top_stack(Stack stk, int val)
{
    if(is_empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  NULL  ;
    }

    stk->data  =  val  ;

    return  stk  ;
}

void  display_stack(Stack stk)
{
    Stack  ptr    =  stk  ;

    if(is_empty_stack(stk))
    {
        cout  <<  "Stack is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

Stack  reverse_stack(Stack stk)
{
    Stack  tmp  =  create_stack()  ;

    int  val  ;

    while(!is_empty_stack(stk))
    {
        stk   =  pop(stk, val)    ;
        tmp   =  push(tmp, val)   ;
    }

    return  tmp  ;
}

int  main()
{
    Stack  stk  =  create_stack()  ;

    stk  =  push(stk, 1)  ;
    stk  =  push(stk, 2)  ;
    stk  =  push(stk, 3)  ;

    display_stack(stk)  ;

    stk  =  reverse_stack(stk)  ;

    display_stack(stk)  ;

    return  0  ;
}

Exercice 5 : (Vérification de parenthèses)

Un fichier texte peut contenir des parenthèses ( ), des crochets [ ], et des accolades { }. Ces éléments peuvent être imbriqués les uns dans les autres (exemple : {a*(b+c[-d])[{e- f }(-g)]} )

Écrire une fonction qui parcourt le fichier texte et détermine si le fichier est correctement parenthèses, c’est-à-dire si toutes les parenthèses, crochets, etc. sont bien refermés par un caractère du même type, et si les parenthèses, crochets et accolades sont correctement imbriqués. Exemple de fichier incorrect : ({)}.

NB : Pour l’exercice n°5 le fichier texte peut être remplacé par une chaine de caractères si les étudiants(es) ne maitrisent pas la notion et l’utilisation des fichiers.

Solution :

#include <iostream>

using  namespace  std  ;

struct  elemenet
{
    char               data  ;
    struct elemenet *  next  ;
};

typedef  struct elemenet Element  ;
typedef  Element *       Stack    ;

Stack  create_stack()
{
    return  NULL  ;
}

bool  empty_stack(Stack stk)
{
    if(stk == NULL)
        return  true  ;
    else
        return  false ;
}

int  depth_stack(Stack stk)
{
    Stack  ptr    =  stk  ;
    int    count  =  0    ;

    while(ptr != NULL)
    {
        count++  ;
        ptr  =  ptr->next  ;
    }

    return  count  ;
}

Stack  push(Stack stk, int val)
{
    Stack  ptr  =  new  Element  ;
    ptr->data   =  val  ;

    ptr->next  =  stk  ;
    stk        =  ptr  ;

    return  stk  ;
}

Stack  pop(Stack stk, int &val)
{
    if(!empty_stack(stk))
    {
        Stack  ptr  =  stk  ;

        val  =  stk->data  ;
        stk  =  stk->next  ;
        delete  ptr        ;

        return  stk  ;
    }
    else
    {
        cout  <<  "Error, the stack is already empty."  <<  endl  ;
        return  NULL  ;
    }
}

int  top_stack(Stack stk)
{
    if(empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  0  ;
    }

    return  stk->data  ;
}

Stack  replace_top_stack(Stack stk, int val)
{
    if(empty_stack(stk))
    {
        cout  <<  "Error, Stack is empty."  <<  endl  ;
        return  NULL  ;
    }

    stk->data  =  val  ;

    return  stk  ;
}

void  display_stack(Stack stk)
{
    Stack  ptr    =  stk  ;

    if(empty_stack(stk))
    {
        cout  <<  "Stack is empty."  <<  endl  ;
        return  ;
    }

    while(ptr != NULL)
    {
        cout  <<  ptr->data  <<  " "  ;
        ptr  =  ptr->next  ;
    }
    cout  <<  endl  ;

    return  ;
}

bool  parentheses_match(char * str)
{
    Stack  stk  =  create_stack()  ;
    int    val  ;

    int  i = 0  ;
    while(str[i] != '\0')
    {
        if((str[i] == '(')||(str[i] == ')')||(str[i] == '[')||(str[i] == ']')||(str[i] == '{')||(str[i] == '}'))
        {
            if((str[i] == '(')||(str[i] == '{')||(str[i] == '['))
            {
                stk  =  push(stk, str[i])  ;
            }
            else
            {
                if(empty_stack(stk))
                {
                    return  false  ;
                }
                else
                {
                    if(((str[i] == ')')&&(top_stack(stk) == '('))||((str[i] == '}')&&(top_stack(stk) == '{'))||((str[i] == ']')&&(top_stack(stk) == '[')))
                    {
                        stk  =  pop(stk, val)  ;
                    }
                    else
                    {
                        while(!empty_stack(stk))
                            stk  =  pop(stk, val)  ;  // drain the stack

                        return  false  ;
                    }
                }
            }
        }

        i++  ;
    }

    if(empty_stack(stk))
        return  true   ;
    else
    {
        while(!empty_stack(stk))
            stk  =  pop(stk, val)  ;// drain the stack

        return  false          ;
    }
}

int  main()
{
    char  str[50]   ;

    cin  >>  str  ;

    if(parentheses_match(str))
    {
        cout  <<  "The expression matches parenthesis."        ;
    }
    else
    {
        cout  <<  "The expression doesn't match parenthesis."  ;
    }

    return  0  ;
}