/*
 * Implemente versões recursivas das rotinas abaixo.
 */
#include <stdlib.h>
#include <stdio.h>

typedef struct No {
  int v;
  struct No* prox;
} No;

int n_elementos (No* p_n) {
  if (p_n == NULL)
    return 0;
  else
    return 1 + n_elementos(p_n->prox);
}

void libera(No* p_n) {
  if (p_n != NULL) {
    libera(p_n->prox);
    free(p_n);
  }
}

int iguais (No* l1, No* l2) {
  if (l1 == NULL && l2 == NULL)
    return 1;
  if (l1 == NULL || l2 == NULL)
    return 0;
  if (l1->v != l2->v)
    return 0;
  return iguais(l1->prox, l2->prox);
}

void insere_final(No** p_p_n, int v) {
  if (*p_p_n == NULL) {
    No* n = malloc(sizeof(No));
    n->v = v;
    n->prox = NULL;
    *p_p_n = n;
  } 
  else
    insere_final(&(*p_p_n)->prox, v);
}

void imprime(No* p) {
  if (p != NULL) {
    printf("%d\n", p->v);
    imprime(p->prox);
  }
}

/************** Aula 07 ****************/

No* cria_no(int v) {
  No* n = (No*) malloc(sizeof(No));
  n->v = v;
  return n;
}

No* concat(No* ap_elem, No* ap_lista) {
  ap_elem->prox = ap_lista;
  return ap_elem;
}

No* copia(No* p) {  
  if (p == NULL)
    return NULL;
  No *n = cria_no(p->v);
  n->prox = copia(p->prox);
  return n;
}


/* 
 * Monta uma lista ligada a partir
 * de uma string do tipo (3,5,6,8,9)
 * lida da entrada padrão.
 */ 
No* cria_lista_padrao () {
}

/* 
 * Monta uma lista ligada a partir
 * de uma string do tipo (3,5,6,8,9)
 * passada como parâmetro.
 */  
No* cria_lista (char* str) {

}



main() {
  No* p_n, *l;

  p_n = concat(cria_no(3), NULL);
  printf("Numero de elementos: %d\n", n_elementos(p_n));
  imprime(p_n);

  p_n = concat(cria_no(0), concat(cria_no(1), 
				  concat(cria_no(2), p_n)));

  printf("Numero de elementos: %d\n", n_elementos(p_n));
  imprime(p_n);

  /*  printf("Lista copiada:\n");  
  l = copia(p_n);
  imprime(l);

  libera(p_n);
  libera(l);

  imprime (cria_lista("(1,2,3)"));

  imprime (cria_lista_padrao()); */


  /* Você consegue liberar os nós das últimas listas criadas? */
  
  return 0;
}