Pessoal!   Nunca postei aqui e realmente estou precisando de ajuda o mais rapido possivel!  Eu tenho um código pronto e preciso adicionar duas funções nele, a de inserir em ordem alfabética e a de remover. eu consegui fazer em listas simplesmente encadeadas mas não consegui em duplamente encadeadas.  Eu tenho três paginas de código: Main.c, LDE.c e LDE.h O código que fiz compila mas da um erro e encerra o programa.  Eu escrevi somente a parte de remover e inserir ordenada, o resto já veio pronto pelo professor.  Vou tentar colocar eles para vocês!   Este é o LDE.c:   #include <stdio.h>
#include <stdlib.h>
#include "LDE.h"
PtNo* inicializa(void)
{
    return NULL;
}
PtNo* destroi(PtNo* ptLista)
{
    PtNo *ptaux; //ponteiro auxiliar para percorrer a lista
    while (ptLista != NULL)
    {
        ptaux = ptLista;
        ptLista = ptLista->prox;
        free(ptaux);
    }
    free(ptLista);
    return NULL;
}
void imprime(PtNo* PtLista)
{
    PtNo* ptaux=PtLista;
    if (PtLista == NULL)
        puts("lista vazia");
    else
        do
        {
            printf("Codigo = %d, Nome = %s, preço = %.2f.\n", ptaux->info.codigo, ptaux->info.nome, ptaux->info.preço);
            ptaux = ptaux->prox;
        }
        while (ptaux != NULL);
}
void imprime_invertida(PtNo *PtLista)
{
    PtNo *PtAux;
    if (PtLista==NULL)
    {
        printf("Lista vazia ! ");
    }
    else
    {
        PtAux=PtLista;
        while (PtAux->prox!=NULL)
            PtAux=PtAux->prox;
        while (PtAux!=NULL)
        {
            printf("Codigo = %d, Nome = %s, preço = %.2f.\n", PtAux->info.codigo, PtAux->info.nome, PtAux->info.preço);
            PtAux=PtAux->ant;
        }
    }
}
PtNo* insere_inicio(PtNo *PtLista, InfoNo Dado)
{
    PtNo *novo;
    novo = (PtNo*) malloc(sizeof(PtNo));
    novo->info = Dado;
    novo->ant = NULL;
    novo->prox = PtLista;
    if (PtLista != NULL)
        PtLista->ant = novo;
    PtLista = novo;
    return PtLista;
}
PtNo* insere_fim(PtNo *PtLista, InfoNo Dado)
{
    PtNo *novo, *PtAux;
    novo = (PtNo*) malloc(sizeof(PtNo));    //aloca novo nodo
    novo->info = Dado;                        //coloca dados no novo nodo
    if ((PtLista) == NULL)                    //lista vazia
    {
        PtLista = novo;
        novo->ant = NULL;
        novo->prox = NULL;
    }
    else                                      // lista tem pelo menos um nodo
    {
        PtAux = PtLista;                    //auxiliar no início da lista
        while (PtAux->prox != NULL)         //PtAux avança até o último elemento da lista
        {
            PtAux=PtAux->prox;
        }
        PtAux->prox = novo;
        novo->ant = PtAux;                    //Encadeia novo com PtAux
        novo->prox = NULL;
    }
    return PtLista;
}
// ---------------------------------------------------
/* IMPLEMENTE O CÒDIGO PARA INSERÇÃO ORDENADA AQUI */
PtNo* insere_ordenada(PtNo *PtLista, InfoNo Dado)
{
       PtNo *novo, *prox; //novo elemento
       PtNo *ant = NULL; //ponteiro auxiliar para a posição anterior
       PtNo *ptaux = PtLista; //ponteiro auxiliar para percorrer a lista
       /*aloca um novo nodo */
       novo = (PtNo*) malloc(sizeof(InfoNo));
       /*insere a informação no novo nodo*/
       novo->info = Dado;
       /*procurando a posição de inserção*/
       while ((ptaux!=NULL) && (strcmp(ptaux->info.nome,Dado.nome)<0)) //se info.titulo < dados.titulo então strcmp retorna um valor menor que zero
       {
             ant = ptaux;
             ptaux = ptaux->prox;
       }
       /*encadeia o elemento*/
       if (ant == NULL) /*o anterior não existe, logo o elemento será inserido na primeira posição*/
       {
             //  puts("inserindo primeiro");
               novo->prox = PtLista;
               PtLista = novo;
       }
       else /*elemento inserido no meio da lista*/
       {
            novo->prox = ant->prox;
            ant->prox = novo;
            novo->prox->ant=novo;
            novo->ant->prox=novo;
       }
        return PtLista;
}
/* IMPLEMENTE O CÒDIGO PARA REMOÇÃO AQUI */
PtNo* remove_no(PtNo *PtLista, char nome[])
{
     PtNo *ant = NULL; //ponteiro auxiliar para a posição anterior
     PtNo *ptaux = PtLista; //ponteiro auxiliar para percorrer a lista
     /*procura o elemento na lista*/
     while (ptaux !=NULL && (strcmp(ptaux->info.nome, nome)))
     {
          ant = ptaux;
          ptaux = ptaux->prox;
     }
     /*verifica se achou*/
     if (ptaux == NULL)
       return PtLista; /*retorna a lista original*/
    if (ant == NULL) /*vai remover o primeiro elemento*/
      PtLista = ptaux->prox;
    else /*vai remover do meio ou do final*/
      ant->prox = ptaux->prox;
      ant->prox->ant=ant;
    free(ptaux); /*libera a memória alocada*/
    return PtLista;
        }
Este é o main.c:
#include <stdio.h>
#include <stdlib.h>
#include "LDE.h"
int main()
{
    int op;
    InfoNo dados;
    char rem[20];
    PtNo *l;
    l = inicializa();
    do
    {
        system("cls");
        printf("1-Inserir no Final\n");
        printf("2-Inserir no Inicio\n");
        printf("3-Inserir Ordenado\n");
        printf("4-Remover\n");
        printf("5-Imprimir\n");
        printf("6-Imprimir Invertida\n");
        printf("0-Fim\n");
        printf("\nDigite sua opcao: ");
        scanf("%d",&op);
        switch(op)
        {
        case 1:
            printf("\n*** Insercao no Fim ***\n\n");
            printf("Codigo: ");
            fflush(stdin);
            scanf("%d",&dados.codigo);
            printf("Nome: ");
            fflush(stdin);
            gets(dados.nome);
            printf("preço: ");
            fflush(stdin);
            scanf("%f",&dados.preço);
            l=insere_fim(l,dados);
            system("pause");
            break;
        case 2:
            printf("\n*** Insercao no Inicio ***\n\n");
            printf("Codigo: ");
            fflush(stdin);
            scanf("%d",&dados.codigo);
            printf("Nome: ");
            fflush(stdin);
            scanf("%s",dados.nome);
            printf("preço: ");
            fflush(stdin);
            scanf("%f",&dados.preço);
            l=insere_inicio(l,dados);
            system("pause");
            break;
        case 3:
            //printf("\n*** Operacao não implementada ***\n\n");
            printf("\n*** Insercao ordenada ***\n\n");
            printf("Codigo: ");
            fflush(stdin);
            scanf("%d",&dados.codigo);
            printf("Nome: ");
            fflush(stdin);
            gets(dados.nome);
            printf("preço: ");
            fflush(stdin);
            scanf("%f",&dados.preço);
            l=insere_ordenada(l,dados);
            system("pause");
            break;
        case 4:
            //printf("\n*** Operacao não implementada ***\n\n");
            printf("\n*** Remocao ***\n\n");
            printf("Qual elemento deseja remover?");
            fflush(stdin);
            gets(rem);
            l = remove_no(l, rem);
            system("pause");
            break;
        case 5:
            printf("\n*** Impressao ***\n\n");
            imprime(l);
            system("pause");
            break;
        case 6:
            printf("\n*** Impressao Invertida ***\n\n");
            imprime_invertida(l);
            system("pause");
            break;
        }
    }
    while (op !=0);
    l=destroi(l);
    return 0;
}
E este o LDE.h:
struct TipoInfoNo
{
    int codigo;
    char nome[20];
    float preço;
};
typedef struct TipoInfoNo InfoNo;
struct TipoPtNo
{
    InfoNo info;
    struct TipoPtNo* ant;
    struct TipoPtNo* prox;
};
typedef struct TipoPtNo PtNo;
PtNo* inicializa(void);
PtNo* destroi(PtNo* ptLista);
void imprime(PtNo* PtLista);
void imprime_invertida(PtNo *PtLista);
PtNo* insere_inicio(PtNo *PtLista, InfoNo Dado);
PtNo* insere_fim(PtNo *PtLista, InfoNo Dado);
PtNo* insere_ordenada(PtNo *PtLista, InfoNo Dado);
PtNo* remove_no(PtNo *PtLista, char nome[]);   Eu preciso fazer as funções de inserir ordenado e remover  Muito obrigado pela paciência!