/********************************************************

   ROT-PIL
   =======

   Rotinas basicas de manipulacao de Pilha:
   - Estruturas de dados com alocacao estatica
   - Insercao no final (topo) do vetor
   - Remocao  do final (topo) do vetor

   Aplicacao tipica:
   - O ultimo a entrar eh o primeiro a sair

   Por: Fernando Osorio
   Data da ultima atualizacao: Out. 2013

*********************************************************/

/* Incluir stdlib.h e stdio.h */

#define FALSO      0
#define VERDADEIRO 1

#define OK         1
#define ERRO       0

typedef int Tipo_Dado;

typedef struct
        {
           Tipo_Dado *Dado;
           int  Base,Topo;
           int  Tamanho;     
        }  Tipo_Pilha;

/***

=> Rotinas de Manipulacao de PILHA - Lista Linear Sequencial (vetor)

void inicializa_pilha (Tipo_Pilha *P; int Qtde);
int  insere_pilha     (Tipo_Pilha *P; Tipo_Dado Dado);
int  retira_pilha     (Tipo_Pilha *P; Tipo_Dado *Dado);
void exibe_pilha      (Tipo_Pilha *P);
int  quantidade_pilha (Tipo_Pilha *P);
int  cheia_pilha      (Tipo_Pilha *P);
int  vazia_pilha      (Tipo_Pilha *P);
int  esvazia_pilha    (Tipo_Pilha *P);

/****/

void inicializa_pilha (P, Qtde)
Tipo_Pilha *P;
int Qtde;
{
  P->Dado=(Tipo_Dado *)calloc(Qtde,sizeof(Tipo_Dado));
  if (P->Dado == NULL) 
  {
     printf("## Erro de Alocacao ##\n");  /* Aborta programa */
     exit(0);
  }
  P->Base=0;
  P->Topo=0;
  P->Tamanho=Qtde;
}

int insere_pilha (P, Dado)
Tipo_Pilha *P;
Tipo_Dado Dado;
{
  if (P->Topo < P->Tamanho)           /* Vetor nao esta cheio ? */
  {
     P->Dado[P->Topo]=Dado;
     (P->Topo)++;
     return(OK);
  }
  else
     return(ERRO);
}

int retira_pilha (P, Dado)
Tipo_Pilha *P;
Tipo_Dado *Dado;
{
  if (P->Topo == P->Base)
     return(ERRO);
  else
  {
     (P->Topo)--;
     *Dado=P->Dado[P->Topo];
     return(OK);
  }
}


void exibe_pilha (P)
Tipo_Pilha *P;
{
  Tipo_Dado dado;
  int cont;

  printf("\n");
  for (cont=(P->Topo)-1; cont >= (P->Base); cont--)
      printf("Vetor[%d]=%d\n",cont,P->Dado[cont]);
  printf("\n");
}

int quantidade_pilha (P)
Tipo_Pilha *P;
{
  return( (P->Topo) - (P->Base) );
}

int cheia_pilha (P)
Tipo_Pilha *P;
{
  if (P->Topo == P->Tamanho)
     return(OK);
  else
     return(!OK);
}

int vazia_pilha (P)
Tipo_Pilha *P;
{
  if (P->Topo == P->Base)
     return(OK);
  else
     return(!OK);
}

int esvazia_pilha (P)
Tipo_Pilha *P;
{
  P->Topo=0;
  P->Base=0;
  /* Nao desaloca o vetor, somente esvazia pilha */
}

/*****************
  Fim: rot-pil.c
******************/

