17_7_17:复杂链表的复制

思路:
有两种解决办法:
第一种:
1,遍历一次链表,构建一条新链表,只复制_data以及_next。
2,再次遍历原来链表,获取每次遍历节点的_random,在一次循环中,再次遍历链表。获取_random指向的位置到头结点的长度。在新链表中,也指向相对位置。
时间复杂度:O(n^2)

第二种:
1,遍历原来的链表,每次循环中,在旧节点后面插入一个新节点。添加的新节点的_data是它前驱节点的_data。
2,第二次遍历构建完成后的新链表,将新节点的_random指向属于旧节点的_random指向节点的_next.
3,根据,奇偶,分离旧链表和新链表。
时间复杂度:O(n)
这里写图片描述

需要注意的情况:
1,复杂链表为NULL
2,复杂链表只有一个节点
3,复杂链表有一个以上节点

//这里采用第二种方法
ComplexNode* Copy(ComplexNode* pHead)
{
    if (NULL == pHead)  //链表为NULL
        return NULL;

    ComplexNode* pNewHead = NULL; //复制所得链表的头结点

    if (NULL == pHead->_next)  //链表只要一个节点
    {
        pNewHead = new ComplexNode;
        pNewHead->_data = pHead->_data;
        pNewHead->_next = NULL;
        pNewHead->_random = pHead->_random;
        return pNewHead;
    }

    //1,添加节点,给新节点的_data,_next赋值
    ComplexNode* pCur = pHead;
    while (pCur)
    {
        ComplexNode* pTemp = new ComplexNode;
        pTemp->_data = pCur->_data;
        pTemp->_next = pCur->_next;
        pTemp->_random = NULL;  //暂时不复制

        pCur->_next = pTemp;

        pCur = pTemp->_next;
    }

    //2,给新节点的_random赋值
    pCur = pHead;
    while (pCur)
    {
        //指向随机指向的节点的后一个节点(新开辟的节点)。
        if (pCur->_random)
            pCur->_next->_random = pCur->_random->_next;
        else
            pCur->_next->_random = NULL;

        pCur = pCur->_next->_next; //每次走两步
    }

    //3,分离添加节点后的链表
    pNewHead = pHead->_next;
    pCur = pHead;   //指向链表中的奇数位置
    ComplexNode* pCur_2 = pNewHead; //指向链表中的偶数位置
    while (pCur)
    {
        pCur->_next = pCur_2->_next;
        pCur = pCur->_next;

        if (pCur)
        {
            pCur_2->_next = pCur->_next;
            pCur_2 = pCur_2->_next;
        }
    }
    pCur_2->_next = NULL; //注意,最后一个节点的next还是指向旧节点。

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