typedef struct con punteros

Iniciado por a1ex, 19 Abril 2019, 18:43 PM

0 Miembros y 1 Visitante están viendo este tema.

a1ex

Hola,
Tengo una duda de como estoy entendiendo el tema de estructuras de datos con punteros. He estado buscando por el foro y no encuentro un problema similar que me aclare lo que hago mal.
Tengo estas estructuras:


// Libro
typedef struct {
    char* titulo;
    char* autor;
} tLibro;


// Nodo de una cola
typedef struct _tColaNode {
    tLibro l;
    struct _tColaNode* siguiente;
} tColaNode;


// Cola
typedef struct {
    tColaNode* primero;
    tColaNode* ultimo;
} tCola;


Entonces lo que estoy intentando es añadir varios elementos a la cola. Más allá del código quiero entender como lo hago porque me parece que lo estoy interpretando mal.
Lo primero que hago es comprobar si la cola está vacía y declaro un tLibro que quiero añadir y lo copio en tCola->tColaNode.primero
Después lo apunto al puntero ultimo para que sea tb el último ya que hay uno solo. Hasta aquí todo bien.

El tema es cuando añado el segundo, ahora mismo lo que hago es hacerlo a tCola->tColaNode.ultimo->siguiente que se supone que es el siguiente valor, no?
Pues aquí es donde creo que estoy interpretando mal la estructura y por lo tanto copiando donde no es.

Si me he explicado bien, alguien sabe donde me confundo?

K-YreX

Como bien has comentado, lo estás interpretando mal. Lo primero que debemos tener en cuenta es un poco de teoría.
  • ¿Cómo funciona una cola?
    Una cola es un contenedor de tipo FIFO (first in, first out) o lo que es lo mismo "el primero en entrar es el primero en salir". Es decir, es como una lista en el que las inserciones se hacen por un extremo y las expulsiones, por el otro. Pongamos un ejemplo de una cola en la que queremos meter los números del 1 al 5 en orden ascendente:

    Cola1: 1
    Cola2: 2 1
    Cola3: 3 2 1
    Cola4: 4 3 2 1
    Cola5: 5 4 3 2 1

    Y ahora vamos a sacar los elementos de la cola. Como hemos dicho antes se sacan por el extremo opuesto, entonces en este caso, por la derecha:

    Expulsion1: 1    Cola: 5 4 3 2
    Expulsion2: 2    Cola: 5 4 3
    Expulsion3: 3    Cola: 5 4
    Expulsion4: 4    Cola: 5
    Expulsion5: 5    Cola: (vacia)


    Teniendo esto claro, pasamos al código que tienes:
  • El puntero <siguiente> de <ultimo> siempre debe apuntar a NULL
  • Las inserciones siempre se hacen en <primero>. Entonces para una nueva inserción se hace siguiendo los siguiente pasos:
    1. Crear nodo nuevo.
    2. <siguiente> del nodo nuevo apunta al mismo nodo que <primero>
    3. <primero> apunta al nuevo nodo.
  • Las expulsiones se hacen siempre del último nodo. Y los pasos serían los siguientes:
    1. Llegamos hasta el penúltimo elemento.
    2. Borramos la memoria del último elemento.
    3. Hacemos que <ultimo> apunte al penúltimo.
    4. Hacemos que <ultimo->siguiente> apunte a NULL.

    Creo que no me he dejado nada; si no es así, pueden decírmelo para corregir lo que sea necesario.
    Suerte :-X
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

srWhiteSkull

#2
No, a1ex la cola es un nodo como otro cualquiera, no es un nodo especial. Se considera el nodo de cola el último nodo (el que apunta null al siguiente).

El concepto de una lista es la de un sistema enlazado por nodos que apuntan hacia el nodo continuo. Cada Nodo dispone de su correspondiente información o mejor dicho el almacenamiento de información es el fin de la lista.

typedef struct {
  Libro * libro;
  void * siguienteNodo;   /* si es null, la lista acaba en este nodo */
} Nodo;


Luego podrías crear funciones para que te den el tamaño, realicen b´suquedas, eliminen, etc.


srWhiteSkull

#3
Ejemplo en C++ :

Código (cpp) [Seleccionar]
#include <iostream>

typedef struct {
   int i=0;
   void * nodoSiguiente;
} Nodo;

void add(Nodo * lista, int i){
   while (lista->nodoSiguiente!=NULL){
       lista=(Nodo*)lista->nodoSiguiente;
   }
   lista->nodoSiguiente = new Nodo; //(Nodo*)malloc(sizeof(Nodo));
   ((Nodo*)(lista->nodoSiguiente))->i=i;
   ((Nodo*)(lista->nodoSiguiente))->nodoSiguiente=NULL; // cola
}

int main(int argc, char** argv) {    
   Nodo * lista= new Nodo; //(Nodo*)malloc(sizeof(Nodo));
   
   lista->i=666;
   lista->nodoSiguiente= new Nodo; //(Nodo*)malloc(sizeof(Nodo));
   ((Nodo*)(lista->nodoSiguiente))->i=999;
   ((Nodo*)(lista->nodoSiguiente))->nodoSiguiente=NULL;
   
   add(lista, 123);
   add(lista, 128);
   
   Nodo * nodo = lista;
   while (nodo!=NULL){
       printf("i= %d\n",nodo->i);
       nodo=(Nodo*)nodo->nodoSiguiente;
   }

   system("PAUSE");    
   return 0;
}


PD Lista simple! y Ojo! hay diferencias en el uso de punteros en C con respecto a C++. Si puedes trabajar con C++ mejor!

a1ex

gracias a todos, ya lo veo más claro.
Y si, es en C (por ahora).

Gracias por la ayuda