复制带随机指针的链表
提示:这个题算是一个复杂链表,因为它里面还有一个random的随机指针,题目要求复制这个复杂链表。
解题思路:①拷贝结点链接在原结点的后面,然后将他们连接起来,②处理拷贝结点的random那么你复制的结点random就是你原结点random的后面一个,③然后拆解出你复制的链表。
①拷贝结点,链接到原节点的后面
Node* cur = head;
//当cur为空的时候,就不需要再继续拷贝结点了,作为结束的判断条件
while(cur)
{
//一个一个创造结点,然后在链接
Node* copy = (Node*)malloc(sizeof(Node));
//一定不要忘记对于malloc出来的结点对其进行初始化,不然里面就是随机值,或许到后面就会出现不必要的错误,麻烦
copy->next = NULL;
copy->random = NULL;
copy->val = cur->val;
//一定要先进行这一步,因为你如果直接和新结点相连接,那么新节点去找原结点的下一个的时候就找不到了
Node* next = cur->next;
cur->next = copy;
copy->next = next;
//让这三个cur copy next 遍历起来
cur = next;
}
2.处理拷贝结点的random
每个拷贝结点都链接在原结点的后面,那么是不是可以认为拷贝结点的random也在原结点random的后面一个。(这里就很好的避开了一种情况----当你的结点中的val出现了两个相同的数值时候,我的random不知道该去找哪一个,因为对于random来说只能通过值来寻找,他并不知道他随机指向的地址,数值相同就是它所能找到的判断标准)
//处理拷贝结点的random
//因为你上面的操作,使你的cur都走到空了,现在我需要重头开始思考问题
cur = head;
while(cur)
{
Node* copy = cur->next;
if(cur->random)
//一定要小心谨慎,你的random是有可能为NULL的
copy->random = cur->random->next;
else
cur->random = NULL;
//然后让其迭代起来
cur = cur->next->next;
}
3.拆解出来拷贝的链表
//③拆解出来拷贝的链表
cur = head;
//题目要求最终返回拷贝链表的头
//如果链表是NULL的,那么你这里的head->next就会崩溃,这也是一种测试用例,需要考虑进去
Node* copyHead = head->next;
while(cur)
{
Node* copy = cur->next;
Node* next = copy->next;
cur->next = next;
if(next)
copy->next = next->next;
else
copy->next = NULL;
//迭代起来
cur = next;
}
完整代码
/**
* Definition for a Node.
* struct Node {
* int val;
* struct Node *next;
* struct Node *random;
* };
*/
//复杂链表里面还有一个random指针
typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) {
if(head == NULL)
return NULL;
//1.拷贝结点链接在原结点的后面
Node* cur = head;
while(cur)
{
//一个一个创造结点,然后在链接
Node* copy = (Node*)malloc(sizeof(Node));
//一定不要忘记对于malloc出来的结点对其进行初始化,不然里面就是随机值,或许到后面就会出现不必要的错误,麻烦
copy->next = NULL;
copy->random = NULL;
copy->val = cur->val;
//一定要先进行这一步,因为你如果直接和新结点相连接,那么新节点去找原结点的下一个的时候就找不到了
Node* next = cur->next;
cur->next = copy;
copy->next = next;
//让这三个cur copy next 遍历起来
cur = next;
}
//处理拷贝结点的random
//因为你上面的操作,使你的cur都走到空了,现在我需要重头开始思考问题
cur = head;
while(cur)
{
Node* copy = cur->next;
if(cur->random)
//一定要小心谨慎,你的random是有可能为NULL的
copy->random = cur->random->next;
else
cur->random = NULL;
//然后让其迭代起来
cur = cur->next->next;
}
//③拆解出来拷贝的链表
cur = head;
//题目要求最终返回拷贝链表的头,一开始我就把它保留下来
Node* copyHead = head->next;
while(cur)
{
Node* copy = cur->next;
Node* next = copy->next;
cur->next = next;
if(next)
copy->next = next->next;
else
copy->next = NULL;
//迭代起来
cur = next;
}
return copyHead;
}
但是这道题的解题思路是有些不好的,因为算是一种侵入式的解题,你在解题的过程中自己修改了原链表,但是在多线程(并发操作时)这个链表还有别人在使用的时候呢?你修改了,那别人在访问他的时候就会出现错误!