How to implement a queue using two stacks

5
Hello, I need to implement a queue using two stacks, that is, I need to insert an integer in stack 1, and when I remove an element all the items in stack 1 must be transferred to stack 2, then make it look like with a queue.

Items in stack 1 can only be transferred if stack 2 is empty, while it is not the elements should be removed from stack 2.

The code for insertion and removal in stack 1 is as follows:

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

typedef struct noLista{
    int info;
    struct noLista *prox;
} Elemento;

    Elemento* criarNovo(int Caractere);
    Elemento* Push(Elemento *Topo, int Caractere);
    Elemento* Pop(Elemento *Topo);
    Elemento* Top(Elemento *Topo);

main () {
    int Dados, i, op;
    Elemento *Pilha = NULL, *aux;

    do{
    system("cls");
    printf("1 - Adicionar elemento\n");
    printf("2 - Remover elemento\n");
    printf("0 - Encerrar\n\n");

    printf("Opcao: ");
    scanf("%d", &op);

    switch(op){
        case 1:
            printf("Digite um inteiro: ");
            scanf("%d", &Dados);

            Pilha = Push(Pilha, Dados);
            printf("Elemento adicionado\n\n");
            system("pause");
            break;

        case 2:
            aux = Top(Pilha);

            if(aux != NULL){
                Pilha = Pop(Pilha);
                printf("Elemento removido\n\n");
                system("pause");
            } else{
                printf("A pilha esta vazia\n\n");
                system("pause");
            }
            break;

        case 3:

            break;

    }
    } while(op!=0);
}

Elemento* criarNovo(int Caractere){
    Elemento *novo;

    novo = (Elemento*) malloc(sizeof(Elemento));
    novo->info = Caractere;
    novo->prox = NULL;

    return novo;
}

Elemento* Push(Elemento *Topo, int Caractere){
    Elemento *novo;

    novo = criarNovo(Caractere);

    novo->prox = Topo;
    Topo = novo;
    return Topo;
}

Elemento* Pop(Elemento *Topo){
    Elemento *aux;

    aux = Topo;
    if(Topo != NULL) {
        Topo = Topo->prox;
        free(aux);
    }
    return Topo;
}

Elemento* Top(Elemento *Topo){
    return Topo;
}

What should I do?

    
asked by anonymous 08.09.2018 / 23:01

2 answers

3
typedef struct item_p
{
    int elemento;
    struct item_p *proximo;
} pilhaItem;

typedef struct
{
    pilhaItem *raiz;
    int tamanho;
} pilha;
pilha* pilha_nova()
{
    /* cria pilha */
    pilha *p = (pilha*) malloc(sizeof(pilha));
    if(p == NULL)
        return NULL;

    /* pilha esta' vazia */
    p->raiz = NULL;
    p->tamanho = 0;

  return p;
}
int pilha_tamanho(pilha *p)
{
    if (p == NULL)
        return -1;

    return p->tamanho;
}
int pilha_top(pilha *p)
{
    pilhaItem *aux;

    if (p == NULL || p->tamanho == 0)
        return NULL;

    aux = p->raiz;
    return aux->elemento;
}
pilhaItem* pilha_novo_elemento(int valor)
{
    /* aloca memoria para a estrutura pilhaItem */
    pilhaItem *item = (pilhaItem *) malloc(sizeof(pilhaItem));
    if(item == NULL)
        return NULL;

    item->elemento=valor;

    /* item ainda nao tem proximo */
    item->proximo = NULL;

    return item;
}
void pilha_push(pilha *p, int valor)
{
    pilhaItem *novo = NULL;

    if (p == NULL || valor == NULL)
        return;

    /* cria novo item */
    novo = pilha_novo_elemento(valor);
    if (novo == NULL)
    return;

    p->tamanho++;

    /* inserir no topo da pilha */
    /* se a pilha esta vazia */
    if (p->raiz == NULL)
    {
        p->raiz = novo;
        return;
    }

    /* primeiro elemento */
    novo->proximo = p->raiz;
    p->raiz = novo;
}
void pilha_pop(pilha *p)
{
    pilhaItem *curr;

    if (p == NULL || p->tamanho == 0)
        return;

    curr = p->raiz;
    p->raiz = curr->proximo;
    p->tamanho--;

    /* liberta memoria associada ao item removido */
    free(curr);
}

Test these functions in ideone (example of how to use)

Main file

main () {
    int Dados, i, op;
    pilha *Pilha1=pilha_nova();
    do{
    system("cls");
    printf("1 - Adicionar elemento\n");
    printf("2 - Remover elemento\n");
    printf("0 - Encerrar\n\n");

    printf("Opcao: ");
    scanf("%d", &op);

    switch(op){
        case 1:
            printf("Digite um inteiro: ");
            scanf("%d", &Dados);

            pilha_push(Pilha1, Dados);
            printf("Elemento adicionado\n\n");
            system("pause");
            break;

        case 2:
            if(Pilha1 != NULL){
                pilha_pop(Pilha1);
                printf("Elemento removido\n\n");
                system("pause");
            } else{
                printf("A pilha esta vazia\n\n");
                system("pause");
            }
            break;

        case 3:

            break;

    }
    } while(op!=0);

    pilha *Pilha2=pilha_nova();
    while(pilha_tamanho(Pilha1)>0){
        pilha_push(Pilha2, pilha_top(Pilha1));
        pilha_pop(Pilha1);
    }
}

The final part of the code places all data from stack 1 on stack 2 as desired.

    pilha *Pilha2=pilha_nova();
    while(pilha_tamanho(Pilha1)>0){
        pilha_push(Pilha2, pilha_top(Pilha1)); //inserir na pilha 2 o valor de pilha 1
        pilha_pop(Pilha1); // remover o topo da pilha 1
    }

The method of moving from one stack to another stack is:

LOOP: {

  • Return the top value of stack 1 and put in stack 2
  • Remove stack top value 1
  • }

        
    09.09.2018 / 00:10
    2

    Since @FabioMorais has already responded with a possible alternative implementation for the problem, I'd like to show an implementation starting from the code it has and changing as little as possible.

    I can not help but make an aside for the nomenclature you are using which is more important than it sounds. Let's look at these lines of code:

    Elemento* criarNovo(int Caractere);
    Elemento* Push(Elemento *Topo, int Caractere);
    int Dados, i, op;
    

    Here you are using camelCase and PascalCase , in addition to defining the parameters of the functions and capitalized variables. The most important thing is to be consistent and always use the same naming style, and the most commonly adopted C pattern is snake_case . In this pattern these instructions would be:

    Elemento* criar_novo(int caractere);
    Elemento* push(Elemento *topo, int caractere);
    int dados, i, op;
    

    Names of structures and classes are common to be capitalized.

    Leaving now for the solution. First you have to create the second stack:

    Elemento *Pilha = NULL, *aux, *Pilha2 = NULL;
    //                              ^---
    

    What will be the stack that will have the items to be removed. The idea now is:

    • If Pilha2 has elements then remove it removes the top from that directly.
    • If it is empty you must first pass all elements from Pilha to Pilha2 and then remove the top from Pilha2

    Implementation:

    case 2:
        if (Top(Pilha2) == NULL){  // se a pilha 2 está vazia
            while (Top(Pilha) != NULL){ //passa tudo da pilha1 para a pilha2
                int removido = Top(Pilha)->info;
                Pilha = Pop(Pilha);
                Pilha2 = Push(Pilha2, removido);
            }
        }
        if(Top(Pilha2) != NULL) { //se existem elementos
            int removido = Top(Pilha2)->info; //remove o primeiro da pilha2
            Pilha2 = Pop(Pilha2);
            printf("Elemento %d removido\n\n", removido);
        } else {
            printf("A pilha esta vazia\n\n");
        }
        break;
    

    See working on Ideone by adding elements 5, 10 and 12 and then removing all

    Visually what happens first is that first everything is added to Pilha1

    Pilha1:
    12 -> 10 -> 5 -> NULL
    
    Pilha2:
    NULL
    

    Then on first removal it makes Pop all of Pilha1 and makes Push to Pilha2 .

    Step 1:

    Pilha1:
    10 -> 5 -> NULL
    
    Pilha2:
    12 -> NULL
    

    Step 2:

    Pilha1:
    5 -> NULL
    
    Pilha2:
    10 -> 12 -> NULL
    

    Step 3:

    Pilha1:
    NULL
    
    Pilha2:
    5 -> 10 -> 12 -> NULL    
    

    After these steps all the removals are done by Pilha2 and so they start by removing in 5, giving the order 5, 10, 12 that works as a queue and not a stack.

        
    09.09.2018 / 17:21