链表面试题之复杂链表的复制

来源:互联网 发布:网络口碑营销趋势 编辑:程序博客网 时间:2024/06/08 16:26

复杂链表的复制:一个链表的每个节点,有一个指向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;}

测试结果:
这里写图片描述