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 のいずれかが null の場合にリスト全体を追加するなど)、問題を解決できると思ったので、このように書きましたが、そうではありませんでした....

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

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 に答える
1

パラメータを変更し、それらの変更を関数の外部に保持する場合は、それらを参照渡しする必要があります-たとえば

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

関数内で変更headXした場合、その変更は関数が戻った後も保持されます。への変更headYと変更headZは、値によって渡されるため、行われません。

于 2012-11-12T19:27:11.773 に答える