复杂链表的复制
来源:互联网 发布:大麦盒子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指向已经调整好。分离出新链表就可以。
原链表: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;}
阅读全文
0 0
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复制复杂的链表
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 2017.7.17
- springmvc Controller请求中参数
- c++primer5第二章
- Eclipse实现hibernate反向工程:从数据库逆向生成实体类和hbm文件
- CSS选择器2
- 复杂链表的复制
- 九宫格-踩地雷
- Codeforces Round #382 (Div. 2) 735B Urbanization
- Java并发编程(10):使用wait/notify/notifyAll实现线程间通信的几点重要说明
- select函数在TCP和UDP回射服务器中的应用
- Java面向对象的三个基本特征及五大原则
- LeetCode(12)--Integer to Roman
- 欢迎使用CSDN-markdown编辑器
- 初识大数据