Подтвердить что ты не робот

Создание конструктора копии для связанного списка

Это домашнее задание

Я работаю над реализацией связанного класса списка для моего класса С++, и конструктор копирования для меня очень запутан.

Связанный список состоит из структур, называемых Elems:

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

info - это отдельный пользовательский класс, который хранится в элементе.

подпись для конструктора копирования:

linkedList::linkedList( const linkedList &v )

Проблема, с которой я сталкиваюсь, в основном использует мою логику и фактически записывает ее как код.

Моя общая идея:

  • Установите головку в v.head(head = v.head)
  • Установите значения Elem в v (pri = v.pri, info = v.info, next = v.next)
  • Повторите шаг, повторив шаг 2.

Это общая идея?

Любая помощь будет отличной. Помните, что это домашнее задание, поэтому нет прямых ответов!

Спасибо за ваше время

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

Спасибо за ваше время!

Я думаю, что я понял:

//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;
}

Я уверен, что работает. Я обратил внимание на некоторые логические снимки, и я не столкнулся с какими-либо проблемами.

4b9b3361

Ответ 1

Вы должны быть осторожны с шагом 1 и частью шага 2. Шаг 1 должен выделить новый node и использовать его как head. На шаге 2 часть о next = v.next, если вы не намерены сделать мелкую копию, неверна.

При копировании контейнера, такого как связанный список, вы, вероятно, хотите получить глубокую копию, поэтому необходимо создать новые узлы и копировать только данные. Указатели next и prior в узлах нового списка должны ссылаться на новые узлы, созданные вами специально для этого списка, а не узлы из исходного списка. Эти новые узлы будут иметь копии соответствующих данных из исходного списка, так что новый список можно считать по значению или глубокой копией.

Вот изображение, изображающее различия между мелким и глубоким копированием:

enter image description here

Обратите внимание, что в части Deep Copy диаграммы ни один из узлов не указывает на узлы в старом списке. Дополнительную информацию о различии между мелкой и глубокой копиями см. В статье Wikipedia о копировании объектов.

Ответ 2

  • Вы не должны устанавливать this->head = v.head. Потому что голова - это просто указатель. Что вам нужно сделать, так это создать новую голову и скопировать значения по отдельности из v.head в новую голову. В противном случае у вас будет два указателя, указывающих на одно и то же.

  • Затем вам нужно будет создать временный указатель Elem, который начинается с v.head и перебирает список, копируя его значения в новые указатели Elem в новую копию.

  • См. выше.

Ответ 3

Что должен сделать ваш экземпляр копии? Он должен скопировать pri - легко. Он должен скопировать info - легко. И если next не является нулевым, он должен также скопировать его. Как вы можете скопировать next? Думайте рекурсивно: ну, next является Elem *, а Elem имеет конструктор копирования: просто используйте его для копирования ссылочного Elem и обратитесь к нему.

Вы также можете решить эту проблему итеративно, но рекурсивное решение гораздо более интуитивное.

Ответ 4

Итак, вот мой ответ (не знаю, подходит ли это вашей домашней работе или нет), у инструкторов иногда есть свои идеи;):

Обычно конструктор копирования должен "копировать" ваш объект. То есть скажем, что у вас есть связанныйList l1 и выполните связанныйList l2 = l1 (который вызывает linkedList:: linkedList (l1)), тогда l1 и l2 являются полностью отдельными объектами в том смысле, что модификация l1 не влияет на l2 и наоборот.

Когда вы просто назначаете указатели, вы не получите реальной копии, так как разыменование и изменение любого из них повлияют на оба объекта.

Вы скорее хотите сделать реальную глубокую копию каждого элемента в своем исходном списке (или сделать копию по требованию, если хотите быть фантазией).

Ответ 5

Ты забыл линию return; после

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

Вам нужно выйти, правильно?