チェーンテーブルコピーアルゴリズム


に質問
単純なチェーンテーブルは既知です.チェーンテーブルをコピーし、ヘッダノードポインタに戻ってください.
解法1:遍歴アルゴリズム
元のチェーンテーブルを最初から巡回し、チェーンテーブルの各ノードを順次コピーします.
ノードの定義は次のとおりです.
struct node {
    int data;
    struct node* next;
};
typedef struct node* pNode;
新しいノードnewNodeコードを作成します.
pNode newNode(int data){
    pNode nd = (pNode)malloc(sizeof(node));
    nd->data = data;
    nd->next = NULL;
    return nd;
}

チェーンテーブル関数をコピーし、最初のノードの特殊な状況に注意します.さらに、チェーンテーブルに新しいノードを挿入するために、テールノードポインタが保持されます.
struct node* copyList(struct node* head) {
    struct node* current = head;
    struct node* newList = NULL; //       
    struct node* tail = NULL; //         
    while (current != NULL) {
        if (newList == NULL) { //     ,      
            newList = newNode(current->data);
            tail = newList;
        }
        else {
            tail->next = newNode(current->data);
            tail = tail->next;
        }
        current = current->next;
    }
    return(newList);
}
最初の新しいノードという特殊な状況を一緒に考慮する場合、ポインタを指すポインタを使用して実現することができる.コードは次のとおりです.
void push(struct node** headRef, int data)
{
    pNode nd = newNode(data);
    nd->next = *headRef;
    *headRef = nd;
}
struct node* copyListWithRef(struct node* head)
{
    struct node* current = head;
    struct node* newList = NULL;
    struct node** lastPtr = &newList;

    while (current != NULL) {
        push(lastPtr, current->data);  
        lastPtr = &((*lastPtr)->next);
        current = current->next;
    }
    return newList;
}

解法2:再帰アルゴリズム
再帰を使用するとコード量が少なく,論理もはっきりしている.主な考え方は,まず元のチェーンヘッダノードをコピーし,関数を再帰的に呼び出してチェーンテーブルの残りをコピーし,新しいチェーンヘッダノードのnextドメインを設定してコピーの残りのチェーンテーブルを指す.コードは次のとおりです.
pNode copyListRecursive(pNode head)
{
    if (head == NULL) return NULL;
    else {
        pNode newList = newNode(head->data);  //        ,        
        newList->next = copyListRecursive(head->next); //    next           
        return newList;
    }
}