左神基础班-拷贝有随机指针的链表
这是是实现的方法。
LinkNode* copyLink(LinkNode* head){
unordered_map<LinkNode*,LinkNode*> map;
LinkNode* go= head;
LinkNode* head_copy = new LinkNode(0);
LinkNode* copy_go = head_copy;
//第一次遍历,建立节点并放到hash_table里
while(go->next != nullptr){
go = go->next;
LinkNode* copy_node = new LinkNode(go->value);
map[go]=copy_node;
}
go = head->next;
//先把copy链表的head与第一个节点连起来,后面的逻辑用循环连接
copy_go->next = map.find(go)->second;
copy_go->rand = nullptr;
copy_go = copy_go->next;
//作为copy链表的 记忆指针
LinkNode* next;
LinkNode* rand;
//然后,此时go指向每一个不为空的节点,copy_go指向go的拷贝节点,
//我们从map中找到其对应节点的next与rand节点,并从map中取出来,让copy_go模仿指向
while(go != nullptr){
//坑死我了。因为没有好好考虑边界条件多花了近一个小时的时间在找自己代码的bug
//但实际上,写的代码没问题,但是就是没有考虑最后节点的两个指针都指向nullptr的情况
if(go->next == nullptr && go->rand ==nullptr){
copy_go->next = nullptr;
head_copy->rand = nullptr;
break;
}
//得到copy的next 与rand节点的指针
next = map.find(go->next)->second;
rand = map.find(go->rand)->second;
//指向
copy_go->next = next;
copy_go->rand = rand;
//更新
go = go->next;
copy_go = copy_go->next;
}
return head_copy;
}
这个是有测试的。
#include<iostream>
#include<stack>
#include<unordered_map>
using namespace std;
struct LinkNode{
int value;
LinkNode* next;
LinkNode* rand;
LinkNode(int a){
value = a;
next = nullptr;
rand = nullptr;
}
};
LinkNode* getLink(int arr[], int length);
void show(LinkNode* head);
LinkNode* copyLink(LinkNode* head);
int main(){
LinkNode* head = new LinkNode(0);
LinkNode* a = new LinkNode(1);
LinkNode* b = new LinkNode(2);
LinkNode* c = new LinkNode(3);
head->next = a;
head->rand = nullptr;
a->next = b;
b->next = c;
a->rand = c;
b->rand = a;
c->rand = nullptr;
LinkNode* get = copyLink(head);
LinkNode* go = get->next;
cout<< "1节点值"<<go->value<<endl;
cout<< "1 next"<<go->next->value<<endl;
cout<< "1 rand"<<go->rand->value<<endl;
go = go->next;
cout<< "2节点值"<<go->value<<endl;
cout<< "2 next"<<go->next->value<<endl;
cout<< "2 rand"<<go->rand->value<<endl;
go = go->next;
cout<< "3节点值"<<go->value<<endl;
if(go->rand==nullptr && go->next==nullptr){
cout << "3 next and rand is :nullptr"<<endl;
}
return 0;
}
LinkNode* copyLink(LinkNode* head){
unordered_map<LinkNode*,LinkNode*> map;
LinkNode* go= head;
LinkNode* head_copy = new LinkNode(0);
LinkNode* copy_go = head_copy;
//第一次遍历,建立节点并放到hash_table里
while(go->next != nullptr){
go = go->next;
LinkNode* copy_node = new LinkNode(go->value);
map[go]=copy_node;
}
go = head->next;
//先把copy链表的head与第一个节点连起来,后面的逻辑用循环连接
copy_go->next = map.find(go)->second;
copy_go->rand = nullptr;
copy_go = copy_go->next;
//作为copy链表的 记忆指针
LinkNode* next;
LinkNode* rand;
//然后,此时go指向每一个不为空的节点,copy_go指向go的拷贝节点,
//我们从map中找到其对应节点的next与rand节点,并从map中取出来,让copy_go模仿指向
while(go != nullptr){
//坑死我了。因为没有好好考虑边界条件多花了近一个小时的时间在找自己代码的bug
//但实际上,写的代码没问题,但是就是没有考虑最后节点的两个指针都指向nullptr的情况
if(go->next == nullptr && go->rand ==nullptr){
copy_go->next = nullptr;
head_copy->rand = nullptr;
break;
}
//得到copy的next 与rand节点的指针
next = map.find(go->next)->second;
rand = map.find(go->rand)->second;
//指向
copy_go->next = next;
copy_go->rand = rand;
//更新
go = go->next;
copy_go = copy_go->next;
}
return head_copy;
}