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

   LISTDUP
   ========

   Rotinas de manipulacao de LISTAS ENCADEADAS DUPLAS:
   - Estruturas de dados com alocacao dinamica
   - Insere no inicio ou no final da lista
   - Insere de modo ordenado (antes ou depois de um nodo qualquer)
   - Remove do inicio ou do final da lista

   Aplicacao tipica:
   - Lista de dinamica de elementos de tamanho variavel

   Por: Fernando Osorio
   Data da ultima atualizacao: 23/02/2001

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

#include <stdio.h>

#define FALSO      0
#define VERDADEIRO 1

#define OK         1
#define ERRO       0

typedef int Tipo_Dado;

typedef struct bloco_ld {
		           Tipo_Dado Dado;
	                   struct bloco_ld  *Proximo, *Anterior;
 			}  Nodo_LD;


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

 => Rotinas de Manipulacao de LISTAS DUPLAMENTE ENCADEADAS
    Alocacao dinamica

***
     
void inicializa_ld         (Nodo_LD **LD);
void posiciona_inicio_ld   (Nodo_LD **LD);
void posiciona_fim_ld      (Nodo_LD **LD);
int insere_antes_ld        (Nodo_LD **LD, Tipo_Dado Dado);
int insere_depois_ld       (Nodo_LD **LD, Tipo_Dado Dado);
int insere_inicio_ld       (Nodo_LD **LD, Tipo_Dado Dado);
int insere_fim_ld	   (Nodo_LD **LD, Tipo_Dado Dado);
int insere_ordenando_ld    (Nodo_LD **LD, Tipo_Dado Dado);
int pesquisa_ld   	   (Nodo_LD **LD, Tipo_Dado Dado);
int remove_nodo_ld         (Nodo_LD **LD, Tipo_Dado *Dado);
int remove_dado_ld         (Nodo_LD **LD, Tipo_Dado *Dado);
int quantidade_ld          (Nodo_LD *LD);
void exibe_ld              (Nodo_LD *LD);
int percorre_lista         (Nodo_LD **LD, Tipo_Dado *Dado);
void apaga_ld              (Nodo_LD **LD);

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

void inicializa_ld (LD)
Nodo_LD **LD;
{
  *LD = NULL;
}


void posiciona_inicio_ld (LD)
Nodo_LD **LD;
{
   if (*LD != NULL)
   {
      while ((*LD) -> Anterior != NULL)
            *LD = (*LD) -> Anterior;
   }
}


int insere_antes_ld (LD, Dado)
Nodo_LD   **LD;
Tipo_Dado Dado;
{
   Nodo_LD *novo, *aux;

   novo=(Nodo_LD *)calloc(1, sizeof(Nodo_LD));
   if (novo == NULL)
      return (ERRO);

   novo -> Dado = Dado;

   if (*LD == NULL)
   {
       *LD = novo;
       novo -> Anterior = NULL;
       novo -> Proximo = NULL;
   }
   else
   {
      aux=(*LD)->Anterior;
      (*LD)->Anterior=novo;
      novo->Proximo=(*LD);
      novo->Anterior=aux;
      if (aux != NULL)
  	  aux->Proximo=novo;
   }
   return(OK);
}


int insere_inicio_ld (LD, Dado)
Nodo_LD   **LD;
Tipo_Dado Dado;
{
   posiciona_inicio_ld(LD);
   return(insere_antes_ld(LD, Dado));
}


/*****

  Programa Principal

*****/

main()
{
  Nodo_LD *ListaDupla;
  
  inicializa_ld(&ListaDupla);
  insere_inicio_ld(&ListaDupla,1);
  insere_inicio_ld(&ListaDupla,2);
  insere_inicio_ld(&ListaDupla,3);

  posiciona_inicio_ld(&ListaDupla);
  
  printf("Nodo 1 - Dado = %d\n",ListaDupla->Dado);
  printf("Nodo 2 - Dado = %d\n",ListaDupla->Proximo->Dado);
  printf("Nodo 3 - Dado = %d\n",ListaDupla->Proximo->Proximo->Dado);

  getch();
}


