Insertion sort in double-linked circular list

4

I'm having trouble insertion sort, it's probably in the stop condition, the problem I'm already experiencing with this problem and so far I have not been able to get out of the place. Could someone give a light? Thank you!

void ordena(Lista *p_l){ //insertion sort

int n;
No_lista *cur, *ptr, *tmp;
if(listaVazia(p_l)) return;
cur = *p_l;
cur = cur->prox;
while(cur!=*p_l){
    n=0;
    ptr=cur;
    tmp=cur->ant;
    cur=cur->prox;
    while (tmp!=*p_l && tmp->info > ptr->info){
        n++;
        tmp=tmp->ant;
    }
    if (n){
        ptr->ant->prox=ptr->prox;
        if (ptr->prox!=*p_l)
            ptr->prox->ant=ptr->ant;
        if (tmp==*p_l){
            tmp=*p_l;
            ptr->ant=*p_l;
            ptr->prox=tmp;
            ptr->prox->ant=ptr;
            *p_l=ptr;
        }
        else{
            tmp=tmp->prox;
            tmp->ant->prox=ptr;
            ptr->ant=tmp->ant;
            tmp->ant=ptr;
            ptr->prox=tmp;
        }
    }
}
    
asked by anonymous 13.04.2016 / 17:30

1 answer

2

Well, you made a mess with pointers and with the algorithm, I modified your code and it's working normally here.

Your if (n) should be a while, since insertion sort performs several changes for each element, in this case you are only performing the first switch.

Furthermore inside the if (n) the code is not working. Try not to use ptr- > prox-> ant, this confuses a lot, create a new variable so the code becomes easier to understand.

I've added additional functions to help you test the code.

#include <stdio.h>
#include <stdlib.h>

typedef struct No_lista{
    struct No_lista *ant;
    struct No_lista *prox;
    int info;
} No_lista;

typedef No_lista* Lista;

void adicionar(int parametro, Lista *inicial){
    if(*inicial == 0 ){
        (*inicial) = malloc(sizeof(No_lista));
        (*inicial)->ant = *inicial;
        (*inicial)->prox = *inicial;
        (*inicial)->info = parametro;
    }else{
        No_lista *aux, *ultimo;
        aux = *inicial;
        while(aux->prox != *inicial)
            aux = aux->prox;
        aux->prox = malloc(sizeof(No_lista));
        ultimo = aux->prox;
        ultimo->ant = aux;
        ultimo->prox = *inicial;
        ultimo->info = parametro;
        (*inicial)->ant = ultimo;
    }
}

void printLista(Lista *inicial){
    No_lista *aux;
    aux = *inicial;
    printf("Imprimindo lista:\n");
    do{
        printf("%d ", aux->info);
        aux = aux->prox;
    }while(aux != *inicial);
    printf("\n");
}

void ordena(Lista *p_l){ //insertion sort
    No_lista *cur, *ptr, *tmp, *aux, *aux_ant, *aux_prox;
//  if(listaVazia(p_l))
//      return;

    cur = *p_l;
    cur = cur->prox;

    // Tratando para o caso da lista com 2 elementos
    if( cur->prox == *p_l){
        if( (*p_l)->info > cur->info)
            (*p_l) = (*p_l)->prox;
        return;
    }

    while(cur!=*p_l){
        ptr=cur;
        tmp=cur->ant;
        cur=cur->prox;

        while (tmp->prox != *p_l && tmp->info > ptr->info){
            aux_ant = tmp->ant;
            aux_prox = ptr->prox;

            aux_ant->prox = ptr;
            ptr->prox = tmp;
            tmp->prox = aux_prox;
            aux_prox->ant = tmp;
            tmp->ant = ptr;
            ptr->ant = aux_ant;

            tmp = ptr;
            ptr = tmp->prox;

            if(ptr==*p_l)
                *p_l = tmp;

            tmp=tmp->ant;
            ptr = ptr->ant;
        }
    }
}

int main()
{
    Lista *li, p = NULL;
    li = &p;

    adicionar(4, li);
    adicionar(1, li);
    adicionar(7, li);
    adicionar(5, li);
    adicionar(2, li);

    printLista(li);
    ordena(li);
    printLista(li);

   // scanf("%*c");
    return 0;
}    

  • Remembering a free in the main is better than two flying malloc!

        
  • 19.04.2016 / 18:46