Pregunta

Estoy tratando de ordenar mi estructura basada en nombres (alfabéticamente).Por ejemplo, tengo esta estructura:

struct person{
    char name[MAX];
    char num[MAX];
    char email[MAX];
    struct person *next;   
    struct person *previous;  
};

struct person *next, *first, *end;

y en mi función principal:

int main()
{
 struct person p = {{0}}
 .
 .
 .
 switch(choice)
    {
    case 1 : 
        printf("Name   : "); scanf("%s", &p.name);
        printf("Num : "); scanf("%s", &p.num);
        printf("E-Mail   : "); scanf("%s", &p.email);
        input(p); //function to input data    
        break;
    case 2 : 
        sort(p); //function to sort the data
        break;
               }
}

y en mi función prototipo:

void sort(struct person p)
{
    struct person *ptr, *ptr2, *temp;

    ptr=first;
    ptr2=first;

    for (ptr= first; ptr!= NULL; ptr= ptr->next)
    {
        for (ptr2= ptr2->next; ptr2!= NULL; ptr2= ptr2->next)
        {
            if (strcmp(ptr->name, ptr2->name) > 0)
            {
                temp = ptr;
                ptr= ptr2;
                ptr2= temp;
            }
        }
    }

}

De acuerdo, así que tengo una función prototipo que ordena la estructura en función de su elemento que se nombra.Intenté clasificarlo usando el mismo principio que Bublesort, pero no funcionó para mí.Puntero PTR apunta al primer nodo en la lista y PTRO2 puntos al segundo nodo.¿Mi algoritmo está mal? Parece que parece descubrir qué está mal.El problema principal es con la clasificación.Espero que mi pregunta sea clara.

¿Fue útil?

Solución

Loop interno

    for (ptr2= ptr2->next; ptr2!= NULL; ptr2= ptr2->next)

debe ser

    for (ptr2= ptr->next; ptr2!= NULL; ptr2= ptr2->next)

(note el ptr2 vs. ptr).

Editar:

Tampoco funcionará los punteros de intercambio.Tienes que reiniciar con elementos que requieren variables de ayuda en los bucles.Las cosas se pueden hacer más elegantes (-> tratar con el jefe de lista) cuando se trabaja con referencias:

static void swap(struct person **a, struct person **b)
{
    struct person       *tmp;

    if ((*a)->next)
        (*a)->next->prev = *b;

    if ((*b)->next)
        (*b)->next->prev = *a;

    tmp        = (*a)->prev;
    (*a)->prev = (*b)->prev;
    (*b)->prev = tmp;

    tmp        = (*a)->next;
    (*a)->next = (*b)->next;
    (*b)->next = tmp;

    tmp = *b;
    *b  = *a;
    *a  = tmp;
}

void foo()
{
    struct person **a;
    struct person *prev_a;

    for (a = &first; *a != NULL; a = &(prev_a->next)) {
        struct person **b;
        struct person *prev_b;

        prev_a = (*a)->prev;

        for (b = &(*a)->next; *b != NULL; b = &(prev_b->next)) {
            prev_b = (*b)->prev;

            if (strcmp((*a)->name, (*b)->name) > 0)
                swap(a, b);

            /* prev_b == NULL can not happen because inner loop is started
               in the middle of the list */
            prev_b = prev_b->next;
        }

        if (prev_a)
            prev_a = prev_a->next;
        else
            prev_a = first;
    }
}

Editar:

Implementación de kernel de Linux como listas vinculadas (que tienen una cabeza ficticia que está vinculada en la parte delantera y cola de la lista) Haga que las cosas sean más fáciles en el método de intercambio porque se pueden omitir las verificaciones del puntero nulo.P.ej.La lista se vería como

     ,------------> HEAD ------------\
    | +------------     <-----------\  \ 
    | |                              |  |
    | `-> elem_n --> ... --> elem_0 -`  |
     `---        <-- ... <--        <---'

Otros consejos

No intercambiar punteros, intercambiar valores.Además, debe inicializar los punteros vacíos para NULL, no están de forma predeterminada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top