为链表创建复制构造函数

发布于 2024-12-10 21:10:45 字数 1440 浏览 0 评论 0原文

这是家庭作业

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

链表由称为 Elems 的结构组成:

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

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

复制构造函数的签名是:

linkedList::linkedList( const linkedList &v )

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

我的总体想法是:

  1. 将 head 设置为 v.head (head = v.head)
  2. 将 Elem 的值设置为 v's (pri = v.pri , info = v.info , next = v.next)
  3. 迭代,重复步骤 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;
}

我很确定这是可行的。我画了一些逻辑图来提供帮助,但没有遇到任何问题。

This is homework

I'm working on implementing a linked list class for my C++ class, and the copy constructor has be very confusing for me.

The linked list is comprised of structs called Elems:

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

info is a separate, custom class that is stored in the Elem.

the signature for the copy constructor is:

linkedList::linkedList( const linkedList &v )

The issue I am having is mostly taking my logic and actually writing it as code.

My general idea is to:

  1. Set head to v.head (head = v.head)
  2. Set the Elem's values to v's (pri = v.pri , info = v.info , next = v.next)
  3. Iterate through, repeating step 2.

Is this the general idea?

Any help would be great. Remember, this is homework, so no direct answers please!

Thank you for your time

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

Thanks for your time everybody!

I think I have it figured out:

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

I'm pretty sure that works. I drew some logical pictures to help, and I didn't run into any issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不忘初心 2024-12-17 21:10:45

您必须小心步骤 1 和步骤 2 的一部分。步骤 1 应分配一个新节点并将其用作 head。在步骤 2 中,有关 next = v.next 的部分,除非您的目的是进行浅复制,否则是不正确的。

当您复制链表等容器时,您可能需要深层复制,因此需要创建新节点并且仅复制数据。新列表节点中的 nextprior 指针应引用您专门为该列表创建的新节点,而不是来自原始清单。这些新节点将具有原始列表中相应数据的副本,因此新列表可以被视为按值或深度副本。

下面是一张图片,描述了浅复制和深复制之间的差异:

在此处输入图像描述

注意深复制中的情况 图中的部分,没有一个节点指向旧列表中的节点。有关浅拷贝和深拷贝之间差异的更多信息,请参阅有关对象复制的 Wikipedia 文章。

You have to be careful with Step 1 and part of Step 2. Step 1 should allocate a new node and use that as the head. In Step 2, the part about next = v.next, unless your intention is to make a shallow copy, is incorrect.

When you copy a container such as a linked list, you probably want a deep copy, so new nodes need to be created and only the data copied over. The next and prior pointers in the nodes of the new list should refer to new nodes you create specifically for that list and not the nodes from the original list. These new nodes would have copies of the corresponding data from the original list, so that the new list can be considered a by value, or deep copy.

Here is a picture depicting the differences between shallow and deep copying:

enter image description here

Notice how in the Deep Copy portion of the diagram, none of the nodes point to nodes in the old list. For more information about the difference between shallow and deep copies, see the Wikipedia article on object copying.

┊风居住的梦幻卍 2024-12-17 21:10:45
  1. 您不应该设置this->head = v.head。因为头只是一个指针。您需要做的是创建一个新头并将值从 v.head 单独复制到新头中。否则,您将有两个指针指向同一事物。

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

  3. 见上文。

  1. You shouldn't set this->head = v.head. Because the head is simply a pointer. What you need to do is to create a new head and copy the values individually from v.head into your new head. Otherwise you'd have two pointers pointing to the same thing.

  2. You then would have to create a temporary Elem pointer that starts with v.head and iterate through the list, copying its values to new Elem pointers into the new copy.

  3. See above.

诗化ㄋ丶相逢 2024-12-17 21:10:45

您的复制构造函数应该复制什么?它应该复制 pri - 简单。它应该复制 info - 也很简单。如果 next 不为空,它也应该复制它。如何复制下一个?思考递归:嗯,next 是一个 Elem *,并且 Elem 有一个复制构造函数:只需使用它来复制引用的 Elem 并参考它。

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

What should your copy constructor copy? It should copy pri - easy. It should copy info- easy as well. And if next is not null, it should copy it, too. How can you copy next? Think recursive: Well, next is an Elem *, and Elem has a copy constructor: Just use it to copy the referenced Elem and refer to it.

You can solve this iteratively, too, but the recursive solution is much more intuitive.

那小子欠揍 2024-12-17 21:10:45

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

通常,复制构造函数应该“复制”您的对象。也就是说,你有 linkedList l1,并执行 linkedList l2 = l1 (调用 linkedList::linkedList(l1)),然后是 l1 和 l2
是完全独立的对象,因为 l1 的修改不会影响 l2,反之亦然。

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

您宁愿对源列表中的每个元素进行真正的深层复制(或者如果您想要更花哨,则仅进行按需复制)。

So here is my answer (don't know if that fits to your homework or not - instructors tend to have their own ideas sometimes ;):

Generally a copy constructor should "copy" your object. I.e. say you have linkedList l1, and do a linkedList l2 = l1 (which calls linkedList::linkedList(l1)), then l1 and l2
are totally separate objects in the sense that modification of l1 doesn't affect l2 and vice versa.

When you just assign pointers you won't get a real copy, as dereferencing and modifying either of them would affect both objects.

You rather want to make a real deep copy of every element in your source list (or do a copy-on-demand only, if you want to be fancy).

浅唱ヾ落雨殇 2024-12-17 21:10:45

你忘记了线
返回;

之后

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

你需要出去,对吧?

You forgot the line
return;
after

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

You need to get out, right?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文