AoA,
He estado intentando depurar un problema en mi lista circular vinculada durante 12 horas. La función toma un ADT que tiene un campo de inicio y cursor. La celda ficticia inicial se apunta a sí misma. Insertar elementos. No se permiten elementos repetidos.
int setInsertElementSorted(setADT buffer, setElementT E) { bool isUnique = true; cellT *previous; previous = buffer->start; buffer->cursor = buffer->start->next; while(buffer->cursor != buffer->start){ if(buffer->cursor->value == E){ isUnique = false; } else if(E < buffer->cursor->value) break; else { previous = buffer->cursor; buffer->cursor = buffer->cursor->next; } } if(isUnique != false){ cellT *newNode = malloc(sizeof(cellT)); newNode->value = E; previous->next = newNode; newNode->next = buffer->cursor; buffer->count++; return (buffer->count); } }El código toma una serie de números enteros y luego los ordena en el parámetro LL. Se supone que debe usarse para un conjunto (por eso no hay entradas repetidas).
La salida para: 9, 8, 7, 6, 5, 4, 3, 2, 1
es... 3, 4, 5, 6, 7, 8, 9 (¿qué pasó con los dos primeros valores?)
Al ingresar algo como: 7, 3, 5, 1, 9, 2
out es solo 7, 9 (por lo que no puede manejar valores separados por más de uno... oO)
Información adicional:
typedef struct cellT { int value; struct cellT *next; } cellT; struct setCDT{ int count; cellT *start; cellT *cursor; }; setADT setNew() { setADT newNode = malloc(sizeof(struct setCDT)); newNode->start = newNode->cursor = malloc(sizeof(cellT)); newNode->start->next = newNode->cursor->next = newNode->start; newNode->count = 0; return (newNode); }setADT es un tipo de puntero a setCDT. setElementT, sin embargo, es solo un simple int . Perdón por la ambigüedad.
Algunas observaciones:
while(buffer->cursor != buffer->start && buffer->cursor->value < E){ if(buffer->cursor->value == E) // never true El value == E dentro del primer ciclo nunca es cierto ya que la condición del ciclo tiene un value < E , por lo que encontrar un valor igual a E dejaría de iterar. Cambie la condición del ciclo a <= E y simplemente return si se encuentra un duplicado en lugar de usar la flag .
La ruta donde flag == false tampoco devuelve un valor (aunque debido al error anterior no es accesible en este momento), y también la memoria asignada para newNode si el error con flag se corrige y E existe en la lista ya.
Lo siguiente parece inútil, y debido a if no { después de else la sangría es muy engañosa:
if(buffer->cursor != buffer->start){ newNode->next = buffer->cursor; // would be harmless in both branches previous->next = newNode; // done in both branches } else // always using { } would make this clear previous->next = newNode; buffer->count++; return (buffer->count); Además, no setADT como un tipo de puntero, es simplemente engañoso y combinado con construcciones como New(setADT) es casi seguro que causará errores.
Mientras tanto, en setNew , dado que solo hay un nodo, reemplace newNode->start->next = newNode->cursor->next = newNode->start; with newNode->start->next = newNode->start ;
Resumen de Cambios:
int setInsertElementSorted(struct setCDT * const buffer, const int E) { cellT *newNode; cellT *previous = buffer->start; buffer->cursor = previous->next; while (buffer->cursor != buffer->start && buffer->cursor->value <= E) { if (buffer->cursor->value == E) { return buffer->count; // duplicate value } previous = buffer->cursor; buffer->cursor = buffer->cursor->next; } if ((newNode = malloc(sizeof(*newNode)))) { newNode->value = E; newNode->next = buffer->cursor; previous->next = newNode; buffer->count++; } return buffer->count; }Si el error persiste, es probable que el error esté en otra parte.
Código para probar:
int main (int argc, char **argv) { struct setCDT *list = setNew(); for (int i = 1; i < argc; ++i) { setInsertElementSorted(list, atoi(argv[i])); } list->cursor = list->start; while ((list->cursor = list->cursor->next) != list->start) { (void) printf("%d\n", list->cursor->value); } return EXIT_SUCCESS; }