复杂链表的复制

来源:互联网 发布:大麦盒子dm4036网络锁 编辑:程序博客网 时间:2024/06/06 02:01
复杂链表带有next指针和random随机指针的链表复制:


原链表:1 -> 2 -> 3 -> 4 ,
random指向:
                      1 -> 3
      2 -> 4
      3 -> 2
      4 -> NULL


思路1  暴力做法
1.先把原链表按照next指针复制为新链表,先不管random指针;
2.按顺序找原链表的每个节点的random指针指向的节点,然后遍历新链表找到对应的节点,吧新链表的randon指向调整,
时间复杂度为O(N*N)


思路2  链表拼接法(用红色节点表示新创建的节点)
1.先按顺序创建和原链表
相同的新节点,然后把新节点连接在原节点后面
如下图,红色为新节点。
//原链表1 -> 2 -> 3 -> 4
//新链表1 -> 1 -> 2 -> 2 -> 3 -> 3 -> 4 -> 4


2.按顺序找到原链表的每个节点的random指向,对应的新链表的节点random,指向原节点random的下一个节点
比如:
原链表 1 -> 3
新链表 1 -> 3
新链表的 3 刚好链接在原链表的 3 后面。


3.此时新链表的random指向已经调整好。分离出新链表就可以。

从头节点开始(从0开始),第偶数个节点是原链表,第奇数个节点是新节点(红色节点)



第二种思路的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1#include <iostream>#include <windows.h>#include <assert.h>using namespace std;typedef int DataType;typedef struct ComplexNode {DataType _data; // 数据 struct ComplexNode* _next; // 指向下一个节点的指针 struct ComplexNode* _random; // 指向随机节点(可以是链表中的任意节点 or 空) }ComplexNode;void Display(ComplexNode* list)  //打印链表{assert(list);ComplexNode* node = list;while (node){cout << node->_data << " ";node = node->_next;}cout << endl;}ComplexNode* Find(ComplexNode* list, int key)  //查找结点{assert(list);ComplexNode* head = list;while (head){if (head->_data == key){return head;}head = head->_next;}return NULL;}ComplexNode* MakeList(DataType* a, int n)    //构建复杂链表{ComplexNode* head = new ComplexNode;head->_data = a[0];ComplexNode* list = head;for (int i = 1; i < n; i++){ComplexNode* node = new ComplexNode;node->_data = a[i];node->_next = NULL;head->_next = node;head = head->_next;node = node->_next;}//_random指针指向Find(list, 1)->_random = Find(list, 3);  //1 -> 3Find(list, 2)->_random = Find(list, 4);  //2 -> 4Find(list, 3)->_random = Find(list, 2); //3 -> 2Find(list, 4)->_random = NULL; //4 -> NULLreturn list;}ComplexNode* CopyList(ComplexNode* list){assert(list);ComplexNode* head = list;ComplexNode* newhead = new ComplexNode;ComplexNode* newlist = newhead;ComplexNode* cur = head;//1.复制新节点,然后链接在被复制的节点后面//原链表1 -> 2 -> 3 -> 4//新链表1 -> 1 -> 2 -> 2 -> 3 -> 3 -> 4 -> 4while (cur){head = cur;ComplexNode* newnode = new ComplexNode;newnode->_data = head->_data;newnode->_next = NULL;cur = head->_next;newnode->_next = head->_next;head->_next = newnode;}//2.找到原链表的_random指针指向的节点(head),新节点的_random 指向 原_random 节点的下一个节点(head->_next)//因为新节和原节点值相同,且新点紧跟在原节点后面head = list;cur = head;ComplexNode* newnode = head->_next;while (cur->_next && newnode->_next){head = cur;head = head->_random;if (head != NULL){newnode->_random = head->_next;}elsenewnode->_random = NULL; //如果原链表的_random指向空 则新节点的_random也指向空cur = cur->_next->_next;newnode = newnode->_next->_next;}//3.分离出新链表。(偶数节点是原链表,奇数节点是新链表)head = list;newhead = head->_next;newlist = newhead;while (head && head->_next){head = head->_next->_next;newhead->_next = head;newhead = newhead->_next;}return newlist;}int main(){int a[] = { 1,2,3,4 };ComplexNode* list = MakeList(a, sizeof(a) / sizeof(a[0]));//Display(list);ComplexNode* newlist = CopyList(list);Display(newlist);system("pause");return 0;}


原创粉丝点击