在双向链表中创建和链接

时间:2015-10-10 14:03:21

标签: c++ linked-list segmentation-fault doubly-linked-list

您好我一直在尝试调试这段代码很长时间,但无法弄清楚原因。任何帮助将不胜感激。

在这里,我试图将两个双重链接列表(不同长度)复制到一个新列表中。但是,当我返回新制作的链表时,节点未连接。有人能告诉我哪里做错了吗?

struct PolyNode
{
    int coef;
    int expx;
    int expy;
    PolyNode* prev;
    PolyNode* next;
}

PolyNode* padd(PolyNode* a, PolyNode* b)
{
    PolyNode* c = new PolyNode;
    PolyNode* c_head =c;
    PolyNode* a_head =a;
    PolyNode* b_head =b;
    c->prev = nullptr;
    c->next = nullptr;

    PolyNode* c_next = c->next;
    PolyNode* c_prev = c->prev;

    while (a != nullptr)
    {
        c->coef = a->coef;
        c->expx = a->expx;
        c->expy = a->expy;
        cout << "\t\t copied c=" << c->coef << c->expx << c->expy << endl;

        if(a->next != nullptr)
        {
            c_next = new PolyNode;
            c_next->prev = c;
            c_prev = c;
            c = c_next;
            a = a->next;
        }
        else
        {
            c_next = new PolyNode;
            c_next->prev = c;
            c_prev = c;
            c = c_next;
            break;
        }
    }

    while (b != nullptr)
    {
        c->coef = b->coef;
        c->expx = b->expx;
        c->expy = b->expy;
        cout << "\t\t copied c=" << c->coef << c->expx << c->expy << endl;

        if(b->next != nullptr)
        {
            c_next = new PolyNode;
            c_next->prev = c;
            c = c_next;
            c_prev = c;
            b = b->next;
        }
        else
        {
            c_next = nullptr;
            break;
        }
    }

    c_next = nullptr;

    int sum = Polylength(a_head) + Polylength(b_head);

    for(int i =0; i< sum-1 ; i++)
    {
        if(c_prev == nullptr)
        {
            break;
        }

        c_next = c;
        c = c_prev;
        c_prev = c_prev->prev;
    }

    c_next = c;
    c = c_prev;
    c_prev = nullptr;

    sortPoly(c); //sortPoly is a function which sorts polynomials from largest to smallest exponents and sum them up if same exponents.
    return c;

}

此外,我不是一个非常有经验的程序员,我正在努力培养一些良好的编程习惯。请建议处理指针和链表的任何常见最佳实践。谢谢! 但问题是,即使在函数的开头,事情也会变坏,我会返回一个没有任何链接到下一个节点的节点。

[EDIT stuyckp]正确缩进代码并添加问题陈述作为最后一句。

1 个答案:

答案 0 :(得分:1)

这段代码充满了bug,如果你正在学习使用指针,你必须一步一步地做一个步骤,并绘制你用指针做的事情。我这样做是为了验证你的代码,问题很快就会出现。

您的基本错误是您似乎认为如下:

PolyNode* c_next = c->next;
PolyNode* c_prev = c->prev;

将以某种方式创建一个仍然属于c节点的变量,而实际上c-&gt; next的值只是null,并且该值被复制到一个新变量中。然后,如果您更改此新变量,则根本不会更改c-&gt;。

我不会解决你所有的问题,但这是朝着正确方向迈出的一步。不要使用所有这些临时工,而是这样做:

while (a != nullptr)
{
    c->coef = a->coef;
    c->expx = a->expx;
    c->expy = a->expy;
    cout << "\t\t copied c=" << c->coef << c->expx << c->expy << endl;

    if(a->next != nullptr)
    {
        c->next = new PolyNode;//make c's next point to a new node
        c->next->prev = c; //make this new nodes prev point to c
        c->next->next = nullptr; //make sure to indicate the end
        c = c_next; //now move c to the next position
        a = a->next; //now move a to the next as well
    }

    ...

我仍然不喜欢这段代码,因为如果a和b都为null,你仍然会分配一个新节点。我会在while循环中分配。并在一开始就将c初始化为空。

您的代码也正在为许多人认为会让调试和维护变得疯狂。这也是为什么有一个复制粘贴代码的原因,而循环和while b循环实际上是相同的。尝试制作一些具有良好名称的细粒度函数,以记录您在其中所做的事情。例如padd对于这个大函数来说是一个非常坏的名字。它没有添加它是复制2个列表并从它们创建一个新列表。

这也不是c ++,它只是简单的c。在c ++中,您将使用不同的方法,将行为添加到方法中的数据结构中。我不会详细说明这一点,我认为你已经足够继续了。