void insert(LISTNODEPTR *sPtr, char value)
{
LISTNODEPTR newPtr, previewPtr, currentPtr;
newPtr
= malloc(sizeof(LISTNODE
));
if (newPtr != NULL) {
newPtr->data = value;
newPtr->nextPtr = NULL;
previousPtr = NULL;
currentPtr = *sPtr;
while (currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if (previousPtr == NULL) {
newPtr->nextPtr = *sPtr; //¿Para que es esta linea?, si sPtr se usa por primera ves con NULL, entonces aqui newPTr.nextPtr valdra NULL?
*sPtr = newPtr; // Como es esta linea no entiendo
}
else {
previousPtr->nextPtr = newPtr; // Para que es esto?
newPtr->nextPtr = currentPtr; // y Esto para que se hace? una explicacion detallada por favor
}
}
else
printf("%c not inserted. No memory available.\n", value
); }
La idea es tener una lista simplemente ordenada y esa función inserta ordenadamente.
*sPtr no es NULO. *sPtr es un puntero a un nodo que se pasa a la función. En general sería el puntero al primer nodo de la lista, es decir el puntero cabecera. Si fuera NULO, la lista estaría vacía. Hay listas que se implementan de manera que al crear la lista ya añadas un Nodo. Todo depende de la implementación que se siga.
Luego verificas si hay memoria, creas el nodo y lo inicializas tatatata...
Con el while recorres la lista enlazada y este ciclo terminará cuando el puntero siguiente de un nodo actual apunte a NULO o también cuando el valor que quieras insertar sea mayor que el valor del nodo actual.
Si previousPtr está a NULL al salir del bucle es que la lista está vacía o hay que insertar en la primera posición.
newPtr->nextPtr = *sPtr;
*sPtr = newPtr;
Verás que sencillo es de enteder.
Si la lista está vacía, *sPtr será NULO y el siguiente del nodo creado apuntará a NULO. Luego hacemos que el puntero cabecera de la lista *sPtr apunte al nuevo nodo creado de tal manera que habrás insertado un nodo en una lista vacía.
*sPtr----->[newPtr]----->NULO
En el caso de que haya uno o más elementos. Imagina que haces *sPtr = newPtr;. En este caso
PERDERÁS LA REFERENCIA A LA LISTA y habrás estropeado tu estructura. Entonces al hacer primero newPtr->nextPtr = *sPtr; te aseguras de que el nuevo nodo creado apunte a la cabeza de la lista y luego tú puedas apuntar con *sPtr a newPtr de tal manera que no perderás la referencia a la lista e insertarás en la primera posición:
Inicialmente: *sPtr----->[newPtr]----->[newPtr2]----->[newPtr3]----->[newPtr4]----->[newPtrN]----->NULO
Hacemos: newPtr->nextPtr = *sPtr;
Entonces: newPtr->nextPtr----->[newPtr]----->[newPtr2]----->[newPtr3]----->[newPtr4]----->[newPtrN]----->NULO
Y finalmente hacemos *sPtr = newPtr;
Entonces: *sPtr----->newPtr->nextPtr----->[newPtr]----->[newPtr2]----->[newPtr3]----->[newPtr4]----->[newPtrN]----->NULO
Por último como previousPtr no es nulo pues haces una inserción en el medio de la lista o al final.
previousPtr->nextPtr = newPtr;
newPtr->nextPtr = currentPtr;
Entonces ahora piensa que tienes que insertar por el medio, tendrás un nodo "anterior" y un nodo "posterior"
Entonces la idea es: [NodoAnterior]------>[NuevoNodoAInsertar]------>[NodoPosterior]
Entonces: previousPtr->nextPtr = newPtr; <= Es la unión NodoAnterior ------> NuevoNodoAInsertar
y newPtr->nextPtr = currentPtr; <= Es la unión NuevoNodoAInsertar ------> NodoPosterior
Por último si insertas al final.
La idea es: [UltimoNodo]------>[NuevoNodoAInsertar]------>NULO <= En este caso currentPtr sería NULO en vez de tener una referencia a un nodo interno distinta del primer nodo.
En la función del delete es necesario usar:
(*sPtr)->data
La función recibe un LISTNODEPTR *sPtr, por tanto deberás usar *sPtr dentro de la función
Por otra parte, el operador de indirección -> tiene prioridad sobre el operador *, por lo que si no pones paréntesis, esa línea será tomada como:
*(sPtr->data)
Y eso no tienen ningún sentido. En cambio:
(*sPtr)->data
Sí que tiene porque con (*sPtr) haces referencia a ese puntero y luego con -> data accedes al campo data de la struct Nodo apuntada por el puntero *sPtr.
Perdón si te lío pero esa es la explicación.
¡Saludos!