Ordenar la estructura en los nombres (lista doblemente vinculada)
-
27-12-2019 - |
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.
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.