链表--复杂链表的复制

来源:互联网 发布:网络远程教育可靠吗 编辑:程序博客网 时间:2024/06/06 21:03

一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。

typedef struct ComplexNode{     DataType _data ; // 数据     struct ComplexNode * _next; // 指向下一个节点的指针     struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点or空) }ComplexNode;

方法一:可以把复制过程分为两部分
第一步先复制每个结点并用_next链接。
第二步复制_random。
那么这时候_random不一定指向此结点后面的结点,也有可能在之前的结点。那么如果从原链表头再开始找就会增加时间复杂度。
这种方法的时间复杂度为O(N*N)

方法二:用空间换时间
有n个结点的链表,我们建一个大小为O(n)的哈希表,这时候查找的时间复杂度就为O(1)
这里用O(n)的空间将时间复杂度降为O(n).

方法三:一个链表,将复制后的结点加在此结点的后面
时间复杂度:O(N)不用辅助空间
三步:
1.拷贝此链表的每一个节点,并把它连接到此结点后面
2.复制_random,假设结点N的_random指向结点s,那么复制后的N‘就指向S‘
3.拆分两个链表。因为复制的节点都在原结点的后面。所以单数的节点为原节点,双数的为复制后的结点。

//第一步://拷贝并且链接结点。void CloneNodes(ComplexNode *pHead){     ComplexNode *pNode = pHead;     while(pNode != NULL)     {          ComplexNode* pClone = new ComplexNode();          pClone->_data = pNode->_data;          pClone->_next = pNode->_next;          pNode->_next = pClone;          pClone->_random = NULL;          pNode = pClone->_next;     }}//第二步://复制复杂链接void ConnectRandomNodes(ComplexNode * pHead){     ComplexNode* pNode = pHead;     while(pNode != NULL)     {          ComplexNode* pClone = pNode->_next;          if(pNode->_random != NULL)               pClone->_random = pNode->_random->_next;          pNode = pClone->_next;     }}//第三步://分开两个链表ComplexNode* ReconnectNodes(ComplexNode* pHead){     ComplexNode* pNode = pHead;     ComplexNode* pCloneHead = pHead;     ComplexNode* pCloneNode = pHead;     if(pNode != NULL)     {          pCloneHead = pCloneNode = pNode->_next;          pNode->_next = pCloneNode->_next;          pNode = pNode->_next;     }     while(pNode != NULL)     {          pCloneNode->_next = pNode->_next;          pCloneNode = pCloneNode->_next;          pNode->_next = pCloneNode->_next;          pNode = pNode->_next;     }     return pCloneHead;}

最后把这三个函数调一下即可。

原创粉丝点击