为链表创建复制构造函数

时间:2011-10-18 18:24:06

标签: c++ linked-list copy-constructor

这是作业

我正在为我的C ++类实现一个链表类,而且复制构造函数对我来说非常混乱。

链表由名为Elems:

的结构组成
struct Elem 
    {
        int pri;
        data info;
        Elem * next;
    };
    Elem * head;

info是一个单独的自定义类,存储在Elem中。

复制构造函数的签名是:

linkedList::linkedList( const linkedList &v )

我遇到的问题主要是采用我的逻辑并将其编写为代码。

我的总体想法是:

  1. 设置为v.head(head = v.head)
  2. 将Elem的值设为v(pri = v.pri,info = v.info,next = v.next)
  3. 迭代,重复第2步。
  4. 这是一般的想法吗?

    任何帮助都会很棒。 请记住,这是作业,所以请不要直接回答!

    感谢您的时间

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

    感谢大家的时间!

    我想我已经弄明白了:

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

    我很确定这很有效。我画了一些逻辑图片来帮助,我没有遇到任何问题。

5 个答案:

答案 0 :(得分:21)

您必须小心步骤1和步骤2的一部分。步骤1应分配一个新节点并将其用作head。在第2步中,除非您打算制作浅层副本,否则关于next = v.next的部分不正确。

复制诸如链表之类的容器时,您可能需要深层复制,因此需要创建新节点并仅复制数据。新列表的节点中的nextprior指针应引用您为该列表创建特定的新节点,而不是原始列表中的节点。这些新节点将具有原始列表中相应数据的副本,因此可以将新列表视为值或深度副本。

这是描绘浅层和深层复制之间差异的图片:

enter image description here

请注意,在图的 Deep Copy 部分中,没有一个节点指向旧列表中的节点。有关浅拷贝和深拷贝之间差异的更多信息,请参阅object copying上的维基百科文章。

答案 1 :(得分:4)

  1. 您不应设置this->head = v.head。因为头部只是一个指针。您需要做的是创建一个新头并将值从v.head单独复制到新头中。否则你会有两个指向同一事物的指针。

  2. 然后,您必须创建一个以Elem开头的临时v.head指针,并遍历列表,将其值复制到新Elem指针到新副本中。

  3. 见上文。

答案 2 :(得分:2)

你的复制构造函数应该复制什么?它应该复制pri - 简单。它应该复制info - 也很容易。如果next不为null,它也应该复制它。如何复制next?认为是递归的:好吧,nextElem *,而Elem有一个复制构造函数:只需使用它来复制引用的Elem并引用它。

你也可以迭代地解决这个问题,但递归解决方案更加直观。

答案 3 :(得分:0)

所以这是我的答案(不知道这是否适合你的作业 - 教师有时会有自己的想法;):

通常,复制构造函数应该“复制”您的对象。即假设你有linkedList l1,并做一个linkedList l2 = l1(调用linkedList :: linkedList(l1)),然后是l1和l2 在l1的修改不影响l2的意义上是完全独立的对象,反之亦然。

当您只是分配指针时,您将无法获得真正的副本,因为取消引用和修改它们中的任何一个都会影响这两个对象。

您更愿意为源列表中的每个元素制作一个真正的深层副本(或者,如果您想要的话,只进行按需复制)。

答案 4 :(得分:0)

你忘了这条线 return;

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

你需要离开,对吧?