Invert Dynamic Stack

0

Can anyone help me with this stack? The purpose is to create a function that invert the values of the stack, I tried to do this use the Invert () function of the code below, but it is not working, when I execute it simply closes the code. If anyone has any ideas, I may be doing the wrong allocation ...

#include <stdio.h>
#include <stdlib.h>

typedef struct elemento{
    int valor;
    struct Elemento *anterior;
} Elemento;

typedef struct pilha{
    struct Elemento *topo;
    int tam;
} Pilha;

Pilha *criaPilha(){
    Pilha *p = (Pilha*)malloc(sizeof(Pilha));
    p->topo = NULL;
    p->tam = 0;
    return p;
}
int vazia(Pilha *p){
    if(p->topo == NULL){
    return -1;
    } else {
    return 2;
    }
}
void empilha(Pilha * p, int v){
Elemento *e = (Elemento*)malloc(sizeof(Elemento));
e->valor = v;
    if(vazia(p) == 2){
        e->anterior = p->topo;
    }
    p->topo = e;
    p->tam++;
}
int desempilha(Pilha *p){
    int val;
    if(vazia(p) == 2){
        Elemento *aux;
        aux = p->topo; //Crio uma variável para ajudar a acessar o elemento anterior armazenado no topo;
        val = aux->valor;
        p->topo = aux->anterior; //Topo passa a ser o elemento anterior
        p->tam--;
        free(aux);
        return val;
    }
}

void maiorMenorMedia(Pilha *p, int *maior, int *media,int *menor){
int r = 0, cont = 0; 
int soma = 0;
int menorc = 99999;
int maiorc = -99999;
while(p->topo != NULL){
    r = desempilha(p);
    if(r > maiorc){
        maiorc = r;
    }
    if(r < menorc){
        menorc = r;
    }
    cont++;
    soma += r;
}
*maior = maiorc;
*media = (soma/cont);
*menor = menorc;
}

int maisElementos(Pilha *a, Pilha *b){
if(a->tam > b->tam){
    return 1;
} else {
    return 0;
}
}
Pilha * inverter(Pilha *pilha){
    int value;
    Pilha * aux = criaPilha();
    while(pilha->topo != 0){
        value = desempilha(pilha);
        empilha(aux, value);
    }
    return aux;
}

int main(int argc, char** argv) {
    Pilha *pteste = criaPilha();
    empilha(pteste, 15);
    empilha(pteste, 16);
    empilha(pteste, 17); 
    printf("%d\n", pteste->tam);

    int maior, media, menor;

    maiorMenorMedia(pteste, &maior, &media, &menor);
    printf("Maior: %d\n", maior);
    printf("menor: %d\n", menor);
    printf("media: %d\n", media);

Pilha *a = criaPilha();
Pilha *b = criaPilha();
empilha(a, 15);
empilha(a, 16);
empilha(b, 15); 
empilha(b, 16);
empilha(b, 17);
empilha(b, 18);

if(maisElementos(a,b) == 1){
    printf("Pilha A tem mais elementos\n");
}else{
    printf("Pilha B tem mais elementos\n");
}

Pilha *z = criaPilha();
z = inverter(b);
int x = 0;
x = desempilha(z);
printf("%d", x);
}
    
asked by anonymous 20.09.2018 / 04:07

1 answer

0

There are several details that are not right although the logic itself is right. I always advise to look with close attention for compiler warnings because they are almost always errors and things to correct.

  • In the definition of the elemento structure:

    typedef struct elemento{
        int valor;
        struct Elemento *anterior;
        //     ^---
    } Elemento;
    

    The typedef is only finalized at the end of the statement so it can not use the name defined by it in the middle of the structure. In addition, typedef is made to be able to use only Elemento and not struct Elemento . So the correct one is:

    typedef struct elemento{
        int valor;
        struct elemento *anterior;
        //     ^---
    } Elemento;
    
  • So the following structure has the same problem:

    typedef struct pilha {
        struct Elemento *topo;
    //      ^-----^
        int tam;
    } Pilha;
    

    Where struct Elemento should be only Elemento because this yes corresponds to typedef you did previously.

  • empilha does not put the last element pointing to NULL and so testing if the stack is in the vazia function, if(p->topo == NULL) { does not work as expected, and starts accessing values outside of% memory that he declared.

    To fix just affect e->anterior = NULL when it is the first element of the Stack:

    void empilha(Pilha * p, int v) {
        Elemento *e = (Elemento*)malloc(sizeof(Elemento));
        e->valor = v;
        if(vazia(p) == 2) {
            e->anterior = p->topo;
        }
        else { //se está vazia porque é o primeiro
            e->anterior = NULL; //mete esse a apontar para NULL
        }
        p->topo = e;
        p->tam++;
    }
    

There are many other things to improve but I leave only the most important things:

  • Avoid using loose (magic) numbers such as if (vazia(p) == 2) . This becomes very difficult to read and easy to miss. You can use #define to define constants that it facilitates.
  • Define function returns for all possible paths. In its function desempilha if the stack is empty it has no return specified.
20.09.2018 / 15:29