2

有 3 个链表,其中 2 个(headX 和 headY)按降序给出,函数的工作是将它们排序为一个列表(headZ)。

出于某种原因,该算法工作正常,但是当它完成并通过递归返回时,3 个指针在它们通过递归“返回”时恢复到它们的旧值。

void SortedMergeRecur(Node* headX, Node* headY, Node* headZ)
{
    if (headX == NULL && headY == NULL)
        return;

else if (headX == NULL && headY != NULL)
{
    if (headZ == 0)
    {
        headZ = headY;
        headY = headY->link;
        headZ->link = NULL;
    }
    else
    {
        headZ->link = headY;
        headY = headY->link;
        headZ = headZ->link;
        headZ->link = NULL;
    }

    SortedMergeRecur(headX, headY, headZ);
}

else if (headX != NULL && headY == NULL)
{
    if (headZ == 0)
    {
        headZ = headX;
        headX = headX->link;
        headZ->link = NULL;
    }
    else
    {
        headZ->link = headX;
        headX = headX->link;
        headZ = headZ->link;
        headZ->link = NULL;
    }

    SortedMergeRecur(headX, headY, headZ);
}

if (headX != NULL && headY != NULL)
{
    if (headX->data > headY->data)
    {
        if (headZ == NULL)
        {
            headZ = headY;
            headY = headY->link;
            headZ->link = NULL;
        }
        else
        {
            headZ->link = headY;
            headY = headY->link;
            headZ = headZ->link;
            headZ->link = NULL;
        }
    }
    else
    {
        if (headZ == NULL)
        {
            headZ = headX;
            headX = headX->link;
            headZ->link = NULL;
        }
        else
        {
            headZ->link = headX;
            headX = headX->link;
            headZ = headZ->link;
            headZ->link = NULL;
        }
    }
    SortedMergeRecur(headX, headY, headZ);
}
}

我知道这部分内容可以简化(例如,如果 headX 或 headY 为空,则附加整个列表)但我这样写是因为我认为它可能会解决问题,但它没有......

4

3 回答 3

3

指针按值复制的方式与变量相同:

void test(int x)
{
    x = 5;
}
int y = 3;
test(y);
//y is 3

相同的想法:

void test(int* x, int* y)
{
    x = y;
}
int a = 5; int b = 6;
int* x = &a;
int* y = &b;
test(x, y);
//x is still &a and y is still &b

如果要更改指针,则必须将指针传递给指针:

void test(int** x, int *y)
{
    *x = y;
}
int a = 5; int b = 6;
int* x = &a;
int* y = &b;
test(&x, y);
//x is now &b and y is still &b
//(note that a and b are still 5 and 6, respectively)

由于您使用的是 C++,另一种选择是通过引用传递:

void test(int*& x, int *y)
{
    x = y;
}
int a = 5; int b = 6;
int* x = &a;
int* y = &b;
test(x, y);
//x is now &b and y is still &b
//(note that a and b are still 5 and 6, respectively)
于 2012-11-12T19:26:47.310 回答
1

如果要修改参数并将这些更改保留在函数之外,则需要通过引用传递它们 - 例如

void SortedMergeRecur(Node*& headX, Node* headY, Node* headZ)
//                         |      
//                 pass by reference

如果您headX在函数内部进行修改,则更改将在函数返回后持续存在。更改headYheadZ不会更改,因为它们是按值传递的。

于 2012-11-12T19:27:11.773 回答
1

请记住,在 C 中,参数总是按值传递,而不是按引用传递。

当您将指针传递给类似的函数时

  void SortedMergeRecur(Node* headX, Node* headY, Node* headZ)

如果您更改(即设置)在调用中使用的实际指针参数headX的主体内的正式指针参数SortedMergeRecur不受影响。

如果您想在函数体中影响它们以便将它们的设置传播给调用者,请声明指向指针的形式指针,例如

  void SortedMergeRecur(Node** pheadX, Node** pheadY, Node** pheadZ)

然后设置在体内:

   *pheadY = (*pheadY)->link;

在 C++ 中,您可以通过引用传递形式参数&

于 2012-11-12T19:27:55.637 回答