鏈表面試題之複雜鏈表的複製

複雜鏈表的複製:一個鏈表的每個節點,有一個指向next指針指向下一個節點,還有一個RandNext指針指向這個鏈表中的一個隨機節點或者NULL,現在要求實現複製這個鏈表,返回複製後的新鏈表。

//ps: 複雜鏈表的結構
struct ComplexNode
{
int data ; // 數據
struct ComplexNode * next; // 指向下一個節點的指針
struct ComplexNode * RandNext; // 指向隨機節點(可以是鏈表中的任意節點 or 空)
};

方法一,先創建一個新鏈表在沒有RandNext時與複雜鏈表完全相同,然後再通過遍歷複雜鏈表的方法,一一給新鏈表的RandNext賦值,這樣顯然比較複雜。所以我們還有另一種方法

方法二:

  1. 在複雜鏈表的每一個節點後面加一個節點的複製,鏈成一個新的鏈表
    這裏寫圖片描述
  2. 我們可以看出規律,要複製原鏈表,就是原鏈表節點randnext指向的節點的next賦給原鏈表節點的next的randnext
    這裏寫圖片描述
  3. 分離兩個鏈表
    這裏寫圖片描述
//添加新的節點,並賦值
void ListInser(ListNode **ppList, int x)
{
    *ppList = (ListNode *)malloc(sizeof(ListNode));
    (*ppList)->data = x;
}
ListNode *ListCopy(ListNode *pList) //複雜鏈表的複製
{
    if(pList == NULL)
    {
        return NULL;
    }
    ListNode *cur = pList;
    ListNode* NewListNode = NULL;
    while(cur != NULL)
    {
        ListInser(&NewListNode, cur->data);//添加節點
        NewListNode->next = cur->next;//新節點插到該節點的後面
        cur->next = NewListNode;
        cur = cur->next->next;//向後走
    }
    cur = pList;
    while(cur)
    {
        cur->next->RandNext = cur->RandNext->next;
        //2.randnext的賦值
        cur = cur->next->next;
    }
    NewListNode = pList->next;//新鏈表頭指針爲NewListNode
    cur = pList;
    ListNode *Newcur = NewListNode;
    while(cur)//分離鏈表
    {
        cur->next = cur->next->next;//
        Newcur->next = cur->next;
        cur = cur->next;
        Newcur = Newcur->next;
    }
    return NewListNode;
}

測試結果:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章