How to implement a queue using two stacks

Hello, I need to implement a queue using two stacks, i.e. I need to insert an integer into Stack 1, and when I am removing an element all items from Stack 1 must be transferred to stack 2, then making it look like a queue.

Items from Stack 1 can only be transferred if stack 2 is empty, while it is not elements must be removed from Stack 2.

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

 #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?

Author: Vinícius Rodrigues, 2018-09-08

2 answers

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 the 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 I put all the data from Stack 1 into Stack 2 as I wanted.

    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: {

  1. return the value from the top of Stack 1 and put in the stack 2
  2. remove value from top of Stack 1

}

 3
Author: Fábio Morais, 2018-09-09 16:30:39

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

I cannot help but make an aside for the nomenclature you are using that is more important than it seems. 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 setting the parameters of the capitalized functions and variables. The most important thing is to be consistent and always use the same naming style, and the most adopted pattern in C 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 often capitalized.

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

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

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

  • if Pilha2 has elements then remove removes the top of that directly.
  • if it is empty you must first pass all the elements to from Pilha to Pilha2 and then remove the top of 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 how it works in Ideone by adding elements 5, 10 and 12 and then removing all

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

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

Pilha2:
NULL

Then on the first removal does Pop to everything from Pilha1 and does 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 removals are done by Pilha2 and so start by removing on 5, giving the Order 5, 10, 12 which works as a queue and not a stack.

 2
Author: Isac, 2018-09-09 15:21:35