elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Dudas con Listas Enlazadas
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Dudas con Listas Enlazadas  (Leído 1,491 veces)
traviatØ

Desconectado Desconectado

Mensajes: 165



Ver Perfil
Dudas con Listas Enlazadas
« en: 1 Noviembre 2012, 16:04 pm »

Hola, sucede que estaba analizando este codigo y lo entiendo casi en su totalidad sin embargo existen unas lineas donde tengo dudas (no entiendo claramente), las cuales estan señaladas con comentarios:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct listNode {
  5.       char data;
  6.       struct listNode *nextPtr;
  7. };
  8.  
  9. typedef struct listNode LISTNODE;
  10. typedef LISTNODE *LISTNODEPTR;
  11.  
  12. void insert(LISTNODEPTR *, char);
  13. char delete(LISTNODEPTR *, char);
  14. int isEmpty(LISTNODEPTR);
  15. void printList(LISTNODEPTR);
  16. void instructions(void);
  17.  
  18. main()
  19. {
  20.      LISTNODEPTR startPtr = NULL;
  21.      int choice;
  22.      char item;
  23.      instructions();
  24.      printf("? ");
  25.      scanf("%d", &choice);
  26.  
  27.      while (choice != 3) {
  28.  
  29.            switch (choice) {
  30.                   case 1:
  31.                        printf("Enter a character: ");
  32.                        scanf("\n%c", &item);
  33.                        insert(&startPtr, item);
  34.                        printList(startPtr);
  35.                        break;
  36.                   case 2:
  37.                        if (!isEmpty(startPtr)) {
  38.                            printf("Enter character to be deleted: ");
  39.                            scanf("\n%c", &item);
  40.  
  41.                            if (delete(&startPtr, item)) {
  42.                                printf("%c deleted.\n", item);
  43.                                printList(startPtr);
  44.                            }
  45.                            else
  46.                                printf("%c not found.\n\n", item);
  47.                        }
  48.                        else
  49.                            printf("List is empty.\n\n");
  50.  
  51.                        break;
  52.                   default:
  53.                       printf("Invalid choice.\n\n");
  54.                       instructions();
  55.                       break;
  56.            }
  57.  
  58.            printf("? ");
  59.            scanf("%d", &choice);
  60.      }
  61.  
  62.      printf("End of run.\n");
  63.      system("pause");
  64.      return 0;
  65. }
  66.  
  67. void instructions(void)
  68. {
  69.     printf("Enter your chice:\n"
  70.     "   1 to insert an element into the list.\n"
  71.     "   2 to delete an element from the list.\n"
  72.     "   3 to end.\n");
  73. }
  74.  
  75. void insert(LISTNODEPTR *sPtr, char value)
  76. {
  77.     LISTNODEPTR newPtr, previewPtr, currentPtr;
  78.  
  79.     newPtr = malloc(sizeof(LISTNODE));
  80.  
  81.     if (newPtr != NULL) {
  82.                newPtr->data = value;
  83.                newPtr->nextPtr = NULL;
  84.  
  85.                previousPtr = NULL;
  86.                currentPtr = *sPtr;
  87.  
  88.                while (currentPtr != NULL && value > currentPtr->data) {
  89.                      previousPtr = currentPtr;
  90.                      currentPtr = currentPtr->nextPtr;
  91.                }
  92.  
  93.                if (previousPtr == NULL) {
  94.                               newPtr->nextPtr = *sPtr; //¿Para que es esta linea?, si sPtr se usa por primera ves con NULL, entonces aqui newPTr.nextPtr valdra NULL?
  95.                               *sPtr = newPtr; // Como es esta linea no entiendo
  96.                }
  97.                else {
  98.                     previousPtr->nextPtr = newPtr; // Para que es esto?
  99.                     newPtr->nextPtr = currentPtr; // y Esto para que se hace? una explicacion detallada por favor
  100.                }
  101.     }
  102.     else
  103.         printf("%c not inserted. No memory available.\n", value);
  104. }
  105.  
  106. char delete(LISTNODEPTR *sPtr, char value)
  107. {
  108.     LISTNODEPTR previousPtr, currentPtr, tempPtr;
  109.  
  110.     if(value == (*sPtr)->data) { // Porque se usan parentesis en *aPtr ? , no es valido sPtr.data? o sPtr->data?
  111.              tempPtr = *sPtr
  112.              *sPtr = (*sPtr)->nextPtr; //Parentesis para que?
  113.              free(tempPtr);
  114.              return value;
  115.     }
  116.     else {
  117.          previousPtr = *sPtr;
  118.          currentPtr : (*sPtr)->nextPtr; //Parentesis para que?
  119.  
  120.          while (currentPtr != NULL && currentPtr->data != value) {
  121.                previousPtr = currentPtr;
  122.                currentPtr = currentPtr->nextPtr;
  123.          }
  124.  
  125.          if (currentPtr != NULL) {
  126.                         tempPtr = currentPtr;
  127.                         previousPtr->nextPtr = currentPtr->nextPtr;
  128.                         free(tempPtr);
  129.                         return value;
  130.          }
  131.     }
  132.  
  133.     return '\0';
  134. }
  135.  
  136. int isEmpty(LISTNODEPTR sPtr)
  137. {
  138.    return sPtr == NULL;
  139. }
  140.  
  141. void printList(LISTNODEPTR sPtr)
  142. {
  143.     if (currentPtr == NULL)
  144.         printf("List is empty.\n\n");
  145.     else {
  146.          printf(The list is:\n");
  147.  
  148.          while (currentPtr != NULL) {
  149.                printf("%c --> ", currentPtr->data);
  150.                currentPtr = currentPtr->nextPtr;
  151.          }
  152.  
  153.          printf("NULL\n\n");
  154.     }
  155. }

Agradecido por su valiosa explicacion

Un saludo  :)


« Última modificación: 1 Noviembre 2012, 16:09 pm por traviatØ » En línea

                     
BatchianoISpyxolo

Desconectado Desconectado

Mensajes: 166


Ver Perfil
Re: Dudas con Listas Enlazadas
« Respuesta #1 en: 1 Noviembre 2012, 16:37 pm »

Código
  1. void insert(LISTNODEPTR *sPtr, char value)
  2. {
  3.     LISTNODEPTR newPtr, previewPtr, currentPtr;
  4.  
  5.     newPtr = malloc(sizeof(LISTNODE));
  6.  
  7.     if (newPtr != NULL) {
  8.                newPtr->data = value;
  9.                newPtr->nextPtr = NULL;
  10.  
  11.                previousPtr = NULL;
  12.                currentPtr = *sPtr;
  13.  
  14.                while (currentPtr != NULL && value > currentPtr->data) {
  15.                      previousPtr = currentPtr;
  16.                      currentPtr = currentPtr->nextPtr;
  17.                }
  18.  
  19.                if (previousPtr == NULL) {
  20.                               newPtr->nextPtr = *sPtr; //¿Para que es esta linea?, si sPtr se usa por primera ves con NULL, entonces aqui newPTr.nextPtr valdra NULL?
  21.                               *sPtr = newPtr; // Como es esta linea no entiendo
  22.                }
  23.                else {
  24.                     previousPtr->nextPtr = newPtr; // Para que es esto?
  25.                     newPtr->nextPtr = currentPtr; // y Esto para que se hace? una explicacion detallada por favor
  26.                }
  27.     }
  28.     else
  29.         printf("%c not inserted. No memory available.\n", value);
  30. }

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.

Código
  1. newPtr->nextPtr = *sPtr;
  2. *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.

Código
  1. previousPtr->nextPtr = newPtr;
  2. 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:

Código
  1. (*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:

Código
  1. *(sPtr->data)

Y eso no tienen ningún sentido. En cambio:

Código
  1. (*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!


« Última modificación: 1 Noviembre 2012, 16:51 pm por BatchianoISpyxolo » En línea

Puede que desees aprender a programar desde 0: www.espascal.es
traviatØ

Desconectado Desconectado

Mensajes: 165



Ver Perfil
Re: Dudas con Listas Enlazadas
« Respuesta #2 en: 1 Noviembre 2012, 22:58 pm »

muy amable hermano, estoy agradecido, ya leere lo que has escrito  :xD gracias  :D saludos  ;)
En línea

                     
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Listas enlazadas en c++
Programación C/C++
N3r0 3 8,567 Último mensaje 13 Julio 2010, 12:42 pm
por N3r0
[C] Listas enlazadas.
Programación C/C++
The Swash 5 31,625 Último mensaje 26 Octubre 2011, 04:56 am
por brians444
listas enlazadas
Programación C/C++
javier210186 3 2,881 Último mensaje 25 Octubre 2011, 02:33 am
por javier210186
Dudas con listas de control de acceso (ACL)
Seguridad
davidel11 0 2,061 Último mensaje 6 Mayo 2018, 13:06 pm
por davidel11
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines