1

関数が新しいリストの「ヘッド」を再帰的に返す方法を理解するのに苦労しています。それらはうまく追加されますが、再帰的に、いわば「自分の場所を保存する」方法がわかりません。

struct node {
    int value;
    node *next;
};

node* append(node *&L1, node *L2)
{
    if(L1->next == NULL) {
        L1->next = L2;
        return L1;
    }
    else if(L2 == NULL) 
       return L1;
    else 
       return append(L1->next, L2);
}
void main()
{
    node *a, *b, *c, *d;
    a=new node;
    b=new node;
    c=new node;
    d=new node;
    a->value = 4;
    a->next = b;
    b->next = NULL;
    b->value = 7;
    c->next = d;
    c->value = 12;
    d->next = NULL;
    d->value = 8;
    append(a,c);
}
4

3 に答える 3

1

再帰関数には、ほとんどの場合、基本ケースと再帰ケースの2つのコンポーネントがあります。それで、あなたは最初にあなたの要件のそれらが何であるかを考えなければなりませんか?

たとえば、2つのリンクリストがあると仮定します:listAとlistB:

  1. 基本ケース:listAに要素がなくなったら、停止します
  2. 再帰的な場合:listAの最後の要素を切り離し、listBの先頭にアタッチします。関数を再帰的に再度呼び出します

上記の擬似コードから、プログラミングを開始するのに十分なものが必要です

于 2013-01-29T04:03:21.053 に答える
1
node* append(node *&L1, node *L2)
{
   if (L1 == NULL)
       L1 = L2;
   else if (L1->next != NULL)
       append(L1->next, L2);
   else
       L1->next = L2;

   // Return the head node of the linked list
   return L1;
}
于 2013-01-29T04:17:50.510 に答える
1

特に、開始時にL1がNULLであることを考慮する必要があります。ありがたいことに、それを考慮すると、実際の追加も考慮されます。

node *append(node *&L1, node* L2)
{
    if (!L1)
        L1 = L2;
    else
        append(L1->next, L2);
    return L1;
}

使い方

些細なケース(L1 = NULL, L2 = <anything>>)

  1. 関数を入力します。L1 = NULLL2 = <<anything>>
  2. if(!L1)満足しています。に割り当てL2L1、を返しL1ます。

通常の場合:(L1 != NULL, L2 = <anything>>)

  1. 関数を入力します。L1 != NULL, L2 = <anything>>
  2. if(!L1)満足していない、再帰、送信L1->next, L2
  3. L1NULL(リストの最後になり、したがって最後になります)になるまで繰り返しを続け、次にそのポインターnextにL2を割り当てます(これも最後になります)。L1next
  4. 結果は常にL1を返します。再帰の最後のバックアウトは、リストの先頭を返します。
于 2013-01-29T04:41:24.493 に答える