Creando un constructor de copia para una lista enlazada

Esto es tarea

Estoy trabajando en la implementación de una clase de lista enlazada para mi clase de C ++, y el constructor de copia ha sido muy confuso para mí.

La lista enlazada se compone de estructuras llamadas Elems:

struct Elem { int pri; data info; Elem * next; }; Elem * head; 

La información es una clase personalizada y separada que se almacena en el Elem.

La firma para el constructor de copia es:

 linkedList::linkedList( const linkedList &v ) 

El problema que tengo es sobre todo tomar mi lógica y escribirla como código.

Mi idea general es:

  1. Poner la cabeza en v.head (cabeza = v.head)
  2. Establezca los valores de Elem en v’s (pri = v.pri, info = v.info, next = v.next)
  3. Iterar a través, repitiendo el paso 2.

¿Es esta la idea general?

Cualquier ayuda sería genial. Recuerde, esto es tarea, así que no hay respuestas directas, por favor!

Gracias por tu tiempo

================================================== ================================================== ================================================== ==============

Gracias por tu tiempo a todos!

Creo que lo tengo resuelto:

 //Copy Constructor LinkedList::LinkedList( const LinkedList &v ) { Elem * p1 = 0;//current Elem * p2 = 0;//next if( v.head == 0 ) head = 0; else { head = new Elem; head -> pri = v.head -> pri; head -> info = v.head -> info; p1 = head; p2 = v.head -> next; } while( p2 ) { p1 -> next = new Elem; p1 = p1 -> next; p1 -> pri = p2 -> pri; p1 -> info = p2 -> info; p2 = p2 -> next; } p1 -> next = 0; } 

Estoy bastante seguro de que funciona. Dibujé algunas imágenes lógicas para ayudar, y no tuve ningún problema.

Debe tener cuidado con el Paso 1 y parte del Paso 2. El Paso 1 debe asignar un nuevo nodo y usarlo como head . En el Paso 2, la parte sobre next = v.next , a menos que su intención sea hacer una copia superficial, es incorrecta.

Cuando copia un contenedor como una lista enlazada, es probable que desee una copia profunda, por lo que es necesario crear nuevos nodos y solo copiar los datos. Los next y prior punteros en los nodos de la nueva lista deben referirse a los nuevos nodos que cree específicamente para esa lista y no a los nodos de la lista original. Estos nuevos nodos tendrían copias de los datos correspondientes de la lista original, de modo que la nueva lista puede considerarse como por valor o copia profunda.

Aquí hay una imagen que muestra las diferencias entre la copia superficial y profunda:

introduzca la descripción de la imagen aquí

Observe cómo en la parte Copia profunda del diagtwig, ninguno de los nodos apunta a nodos en la lista anterior. Para obtener más información acerca de la diferencia entre copias poco profundas y profundas, consulte el artículo de Wikipedia sobre la copia de objetos .

  1. No deberías configurar this->head = v.head . Porque la cabeza es simplemente un puntero. Lo que debe hacer es crear una nueva cabecera y copiar los valores individualmente desde v.head en su nueva cabecera. De lo contrario tendrías dos punteros apuntando a la misma cosa.

  2. Luego tendría que crear un puntero Elem temporal que comience con v.head e iterar a través de la lista, copiando sus valores a los nuevos punteros Elem en la nueva copia.

  3. Véase más arriba.

¿Qué debería copiar tu constructor de copia? Debe copiar pri – fácil. Debe copiar info – fácil también. Y si el next no es nulo, también debería copiarlo. ¿Cómo se puede copiar a next ? Piense recursivo: bueno, el next es un Elem * , y Elem tiene un constructor de copia: solo úselo para copiar el Elem al que se hace referencia y refiérase a él.

También puede resolverlo de forma iterativa, pero la solución recursiva es mucho más intuitiva.

Así que aquí está mi respuesta (no sé si eso se ajusta a su tarea o no, los instructores tienden a tener sus propias ideas a veces;):

En general, un constructor de copias debe “copiar” su objeto. Es decir, tiene la lista enlazada l1 y realiza una lista enlazada l2 = l1 (que llama a linkList :: linkedList (l1)), entonces l1 y l2 son objetos totalmente separados en el sentido de que la modificación de l1 no afecta a l2 y viceversa.

Cuando solo asignas punteros no obtendrás una copia real, ya que la eliminación de referencias y la modificación de cualquiera de ellos afectaría a ambos objetos.

Prefiere hacer una copia en profundidad real de cada elemento de su lista de fonts (o hacer una copia a pedido solamente, si quiere ser elegante).

Olvidaste la línea de return; después

 if( v.head == 0 ) head = 0; 

Necesitas salir, ¿verdad?