aula 227

Segunda versão para a estrutura de dados dinâmica do tipo PILHA

Agora que já aprendemos como funciona a estrutura de dados dinâmica pilha e fizemos uma implementação em C, vamos aprender uma segunda versão para implementar uma estrutura de dados dinâmica do tipo pilha que pode ser um pouco mais fácil de entender.

Para a implementação que finalizamos na aula anterior nós criamos apenas uma estrutura para nossa pilha, a estrutura . Assim, nossa pilha é uma sequência de nós encadeados. Ao implementar dessa forma, precisamos usar ponteiro para ponteiro ao desempilhar um elemento para conseguir alterar o topo da pilha na função main.

Agora vamos criar uma outra estrutura chamada Pilha, esta estrutura terá em seu interior um ponteiro para um Nó chamado topo. Ao utilizar esta abordagem, perceba que o topo da nossa pilha agora estará dentro da estrutura Pilha. Assim, basta passarmos o ponteiro para nossa Pilha e teremos acesso ao topo para realizar qualquer operação.

// estrutura Pilha

typedef struct{
    No *topo;
    int tam;
}Pilha;

Como agora também temos uma estrutura chamada Pilha, vamos desenvolver um procedimento para inicializar corretamente nossa estrutura. Lembre-se que inicialmente toda pilha está vazia, então precisamos dizer que o topo é nulo e o tamanho é zero, assim:

// procedimento para inicializar uma variável do tipo Pilha

void criar_pilha(Pilha *p){
    p->topo = NULL;
    p->tam = 0;
}

Com a estrutura Pilha, não precisamos mais retornar o novo Nó a ser empilhado. Assim, nossa função empilhar vira um procedimento recebendo como parâmetro nossa estrutura Pilha.

void empilhar(Pilha *p){
    No *novo = malloc(sizeof(No));

    if(novo){
        novo->p = ler_pessoa();
        novo->proximo = p->topo; // novo nó aponta para o topo atual
        p->topo = novo; // o topo passa a ser o novo nó
        p->tam++;
    }
    else
        printf("\nErro ao alocar memoria...\n");
}

O processo para desempilhar continua sendo uma função, pois retornamos o Nó desempilhado. Contudo, agora recebemos o ponteiro para nossa Pilha e não mais um ponteiro para ponteiro, pois o topo a ser alterado agora está dentro da estrutura Pilha.

No* desempilhar(Pilha *p){
    if(p->topo){
        No *remover = p->topo; // remover aponta para o topo
        p->topo = remover->proximo; // o topo passa a ser o próximo de remover
        p->tam--;
        return remover;
    }
    else
        printf("\nPilha vazia!\n");
    return NULL;
}

Por fim, também precisamos alterar a função main. Agora nossa variável para a pilha não será mais do tipo Nó, mas do tipo Pilha. Em seguida, precisamos inicializar corretamente nossa pilha com o procedimento criar_pilha, para só depois começar a realizar inserções e remoções na Pilha.

Código completo em C para a nova versão da estrutura de dados do tipo Pilha

/*
            Aula 224: Estrutura de dados PILHA: Segunda versão

            Código escrito por Wagner Gaspar
            Julho de 2021
*/

typedef struct{
    int dia, mes, ano;
}Data;

typedef struct{
    char nome[50];
    Data data;
}Pessoa;

typedef struct no{
    Pessoa p;
    struct no *proximo;
}No;

typedef struct{
    No *topo;
    int tam;
}Pilha;

Pessoa ler_pessoa(){
    Pessoa p;
    printf("\nDigite nome e data de nascimento dd mm aaaa:\n");
    scanf("%49[^\n]%d%d%d", p.nome, &p.data.dia, &p.data.mes, &p.data.ano);
    return p;
}

void imprimir_pessoa(Pessoa p){
    printf("\nNome: %s\nData: %2d/%2d/%4d\n", p.nome, p.data.dia, p.data.mes, p.data.ano);
}

void criar_pilha(Pilha *p){
    p->topo = NULL;
    p->tam = 0;
}

void empilhar(Pilha *p){
    No *novo = malloc(sizeof(No));

    if(novo){
        novo->p = ler_pessoa();
        novo->proximo = p->topo;
        p->topo = novo;
        p->tam++;
    }
    else
        printf("\nErro ao alocar memoria...\n");
}

No* desempilhar(Pilha *p){
    if(p->topo){
        No *remover = p->topo;
        p->topo = remover->proximo;
        p->tam--;
        return remover;
    }
    else
        printf("\nPilha vazia!\n");
    return NULL;
}

void imprimir_pilha(Pilha *p){
    No *aux = p->topo;
    printf("\n----------- PILHA Tam: %d --------------\n", p->tam);
    while(aux){
        imprimir_pessoa(aux->p);
        aux = aux->proximo;
    }
    printf("\n--------- FIM PILHA ------------\n");
}

int main(){

    No *remover;
    Pilha p;
    int opcao;

    criar_pilha(&p);

    do{
        printf("\n0 - Sair\n1 - Empilhar\n2 - Desempilhar\n3 - Imprimir\n");
        scanf("%d", &opcao);
        getchar();

        switch(opcao){
        case 1:
            empilhar(&p);
            break;
        case 2:
            remover = desempilhar(&p);
            if(remover){
                printf("\nElemento removido com sucesso!\n");
                imprimir_pessoa(remover->p);

                free(remover);
            }
            else
                printf("\nSem no a remover.\n");
            break;
        case 3:
            imprimir_pilha(&p);
            break;
        default:
            if(opcao != 0)
                printf("\nOpcao invalida!!!\n");
        }
    }while(opcao != 0);

    return 0;
}

Deixe um comentário

oito + dezenove =

Wagner Gaspar

Capixaba de São Gabriel da Palha, Espírito Santo. Bacharel em Ciência da Computação pela Universidade Federal do Amazonas e mestre em informática pela Universidade Federal do Espírito Santo.