首页 > 代码库 > 算法题:复制复杂链表之空间换时间法
算法题:复制复杂链表之空间换时间法
说明:本文仅供学习交流,转载请标明出处,欢迎转载!
题目:复制一个复杂链表,所谓复杂链表指的是每个节点含有两个指针,一个指向单链表的下一个结点,一个指向单链表中的任意某个结点,或者该指针为空。
为了方便起见,我们将待复制的链表称为原型链表,将复制后的新链表称为复制链表,将指向下一个结点的指针定义为next指针,指向其他位置的指针定义为any指针。《剑指offer》上给出了三种解决方法:(1)常规法;(2)空间换时间法;(3)紧随复制法。书上并给出了第三种方法的实现代码。这里我根据书上的提示,给出第二种方法的代码。
在给出代码之前我们先理解下实现的算法思想。我们知道,如果没有any指针,我们可以很容易得完成复制任务。但是有了any指针,我们就需要考虑如何复制每一个结点的any指针。算法2给出的思想是在构建一个单链表的过程中,设置复制结点与原型结点的一一映射关系,这样在创建完新的单链表之后,我们可以通过原型结点的any指针指向的结点位置,通过查询映射表来获得复制结点的any指针的指向,显然我们可以用hash表或者其他具有映射思想的数据结构,如红黑树。在C++STL中,我们可以采用map容器来实现这一映射。
为了更清晰地理解该复制过程,我们给出如下复杂链表:
该复制链表的创建代码如下:
#include<iostream> #include<map> using namespace std; struct Node { int value; Node* next; Node* any;//指向某个结点 Node(int v):value(v),any(NULL),next(NULL){} }; /*创建一个链表,1->2->3->4->5->6->7*/ Node* CreateList()//创建一个单链表 { Node *head; Node *n1=new Node(1); Node *n2=new Node(2); Node *n3=new Node(3); Node *n4=new Node(4); Node *n5=new Node(5); Node *n6=new Node(6); Node *n7=new Node(7); head=n1; n1->next=n2; n1->any=n3; n2->next=n3; n2->any=n4; n3->next=n4; n4->next=n5; n5->any=n7; n5->next=n6; n6->next=n7; n7->next=NULL; return head; } void FreeList(Node *head)//将链表空间释放 { if(head==NULL) { return ; } else { Node *temp=head->next; delete head; head=temp; FreeList(head); } } void VisitList(Node *head)//遍历链表中的元素,用递归的方法遍历 { if(!head) return ; Node *p=head; while(p) { cout<<"("<<p->value; if(p->any) { cout<<","<<p->any->value<<")"; } else { cout<<",nil)"; } if(p->next) { cout<<"->"; } p=p->next; } cout<<endl; }
复制复杂链表的实现代码如下:
Node *Clone(Node *head)//用hash法保存any指针 { if(head==NULL)return NULL; Node *p=head;//p用于扫描原链表 Node *head1=NULL,*p1=NULL;//head1指向复制链表,p1用于扫描复制链表 map<Node*,Node*>m; while(p)//依次复制将结点值和next指针 { if(!head1) { p1=new Node(p->value); head1=p1; } else { p1->next=new Node(p->value); p1=p1->next; } m[p]=p1;//建立原结点与新结点直接的映射关系 p=p->next; } p=head; p1=head1; while(p)//依次复制每个结点的any指针 { p1->any=m[p->any]; p=p->next; p1=p1->next; } return head1; }测试代码如下:
int main() { Node *head=CreateList(); cout<<"原链表输出为:"; VisitList(head); Node *head1=Clone(head); cout<<"复制链表输出为:"; VisitList(head1); FreeList(head);//释放链表空间 return 0; }
测试结果如下:
参考资料------------《剑指offer》
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。