单链表习题(进阶二)——复杂链表复制
来源:互联网 发布:win7 443端口服务 编辑:程序博客网 时间:2024/06/03 06:47
题目
复杂链表的复制。一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。
解法一
(暴力求解)
1. 这个复杂链表是以单链表为基础的,可以先复制一个单链表,random 指针在原链表上的位置与新链表是相对应的,建立同步投影指针 shadow,与 cur 在原链表上同步,找新链表上的 random ,(如果找不到,说明原链表指针指向了未知地址)。
2. 考虑复杂情况,原链表带环,可以找到入口点并记录,将带环链表转化为无环链表处理,再处理无环的情况。
写代码
- 处理空链表情况
- 用找环入口点函数判断是否带环
- 若带环,先复制尾,到入口点,复制环,又到入口点,复制完毕,拆环(原链表),保留尾,接环用。然后就是不带环链表 random 指针的复制。
- 若不带环,不带环链表复制。
- 复制 random 封装函数(要用两次,还很长)。
代码
//尾插void PushBackCom(ComplexNode** ppList, int x){ assert(ppList); ComplexNode* newTail = (ComplexNode*)malloc(sizeof(ComplexNode)); newTail->data = x; newTail->next = NULL; newTail->random = NULL; if (*ppList == NULL) *ppList = newTail; else{ ComplexNode* plist = *ppList; while (plist->next != NULL){ plist = plist->next; } plist->next = newTail; }}//求入口点ComplexNode* IntranceOfRingCom(ComplexNode* pList){ ComplexNode* fast = pList; ComplexNode* slow = pList; while (fast && fast->next) { fast = fast->next->next; slow = slow->next; if (fast == slow) break; } if (fast != slow || fast->next == NULL) return NULL; while (pList != slow) { pList = pList->next; slow = slow->next; } return pList;}void copyRandom(ComplexNode* cur, ComplexNode* n_cur){ ComplexNode* newComList = n_cur; ComplexNode* pList = cur; while (n_cur != NULL) { if (cur->random != NULL) { ComplexNode* shadow = newComList; ComplexNode* cur2 = pList; while (cur->random != cur2 && cur2 != NULL) { shadow = shadow->next; cur2 = cur2->next; } n_cur->random = shadow; if (shadow == NULL)//在这里出现NULL,意味着有random指向非本链表的位置 printf("warn : point to unknowed node."); } else n_cur->random = NULL; n_cur = n_cur->next; cur = cur->next; } }ComplexNode* copyComplexList(ComplexNode* pList){ if (pList == NULL)return NULL; ComplexNode* intr = IntranceOfRingCom(pList); ComplexNode* newComList = NULL; PushBackCom(&newComList, pList->data); if (intr != NULL) { ComplexNode* n_intr = newComList; ComplexNode* n_cur = newComList; ComplexNode* cur = pList; while (cur != intr)//尾复制 { cur = cur->next; PushBackCom(&n_cur, cur->data); n_cur = n_cur->next; n_intr = n_intr->next; } while (cur->next != intr)//环复制 { cur = cur->next; PushBackCom(&n_cur, cur->data); n_cur = n_cur->next; } copyRandom(pList, newComList); //接环,现在n_cur刚好是尾 n_cur->next = n_intr; } else { ComplexNode* n_cur = newComList; ComplexNode* cur = pList; while (cur->next != NULL) { cur = cur->next; PushBackCom(&n_cur, cur->data); n_cur = n_cur->next; } copyRandom(pList, newComList); } return newComList;}
方法二
(没有处理带环情况,可参考方法一处理带环情况)
代码
ComplexNode* copyComplexList2(ComplexNode* pList){ if (pList == NULL)return NULL; ComplexNode* cur = pList; ComplexNode* newcode; while (cur != NULL) { newcode = (ComplexNode*)malloc(sizeof(ComplexNode)); newcode->data = cur->data; newcode->next = cur->next; newcode->random = NULL; cur->next = newcode; cur = cur->next->next; } cur = pList; newcode = pList->next; while (cur != NULL) { if (cur->random != NULL) newcode->random = cur->random->next; newcode = cur->next; cur = cur->next->next; } newcode = pList->next; ComplexNode* ret = pList->next; cur = pList; cur->next = cur->next->next; cur = cur->next; while (cur != NULL) { newcode->next = newcode->next->next; cur->next = cur->next->next; cur = cur->next; newcode = newcode->next; } return ret;}
阅读全文
0 0
- 单链表习题(进阶二)——复杂链表复制
- 复杂链表的复制(二)
- 链表面试题(进阶)&&复杂链表的复制
- 面试算法(二十五)复杂链表的复制
- 链表—复杂链表的复制
- 复制复杂链表
- 复制复杂链表
- 复杂链表复制
- 复制复杂链表
- 复制复杂链表
- 复制复杂链表
- 复杂链表复制
- 复杂链表复制
- 复杂链表复制
- 复杂链表复制
- 复杂链表复制
- 剑指offer之二十一---复杂链表的复制
- 【数据结构】单链表--复杂链表的复制
- openlayer3热力图的实现 Heatmap
- Manifest merger failed with multiple errors, see logs问题处理
- 记录C++学习bug历程
- Android7.0中文文档(API)-- Toolbar
- java集合类的一些内建函数分析
- 单链表习题(进阶二)——复杂链表复制
- 使用连接mysql的jdbc驱动最新版引发的问题
- android Service发送广播
- sqlite3用法
- window 下使用GNU工具的方法
- Android之Canvas.drawCircle()方法的理解
- TextView设置drawable
- MFC中 给按钮添加图片的方法
- kettle5.3源码部署