复杂链表的复制(随机指针)

2024-06-22 14:18

本文主要是介绍复杂链表的复制(随机指针),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意描述:请实现函数ComplexListNode *Clone(ComplexListNode* head),复制一个复杂链表。在复杂链表中,每个结点除了有一个pNext指针指向一下一个结点外,还有一个pOther指向链表中任意结点或NULL。结点的定义如下:

struct ComplexListNode {int val;ComplexListNode* pNext;ComplexListNode* pOther;
};

复杂链表如图所示:

解题思路:这里分为三个步骤:
1)复制链表,复制原始链表的任意结点N并创建新结点N`,再把N`链接到N的后面;
2)设置结点的pOther指针对应的结点,如果原始链表上结点N的pOther指针指向S,则它对应的复制结点N`的pOther指针就指向S的下一个结点S`;

3)将链表拆分为两个链表,把奇数位置的结点用pNext指针链接起就是原始链表,偶数位置用pNext指针链接起来就是复制的链表;

处理过程如图:

 

//1)复制原始链表的任意结点N并创建新结点N`,再把N`链接到N的后面
void CloneNodes(ComplexListNode* head) {ComplexListNode* pNode = head;while (pNode != NULL) {ComplexListNode* tmpNode = new ComplexListNode();tmpNode->val = pNode->val;tmpNode->pNext = pNode->pNext;tmpNode->pOther = NULL;pNode->pNext = tmpNode;pNode = tmpNode->pNext;}
}//2)设置结点的pOther指针对应的结点,如果原始链表上结点N的pOther指针指向S,则它对应的复制结点N`的pOther指针就指向S的下一个结点S`
void SetpOther(ComplexListNode* head) {ComplexListNode* pNode = head;while (pNode != NULL) {if (pNode->pOther != NULL)pNode->pNext->pOther = pNode->pOther->pNext;pNode = pNode->pNext->pNext;}
}//3)将链表拆分为两个链表,把奇数位置的结点用pNext指针链接起就是原始链表,偶数位置用pNext指针链接起来就是复制的链表
ComplexListNode* SplitList(ComplexListNode* head) {ComplexListNode* pNode = head;ComplexListNode* CopyHead = NULL;ComplexListNode* pCopyNode = NULL;if (pNode != NULL) {//设置新链表表头CopyHead = pNode->pNext;pNode->pNext = CopyHead->pNext;pNode = pNode->pNext;}pCopyNode = CopyHead;while (pNode != NULL) {pCopyNode->pNext = pNode->pNext;pCopyNode = pCopyNode->pNext;pNode->pNext = pCopyNode->pNext;pNode = pNode->pNext;}return CopyHead;
}ComplexListNode* CloneList(ComplexListNode* head) {CloneNodes(head);SetpOther(head);ComplexListNode* pNewHead = SplitList(head);return pNewHead;
}
//打印链表
void ShowList(ComplexListNode* head) {ComplexListNode* pNode = head;cout << "\t" << "顺序链表输出:";while (pNode != NULL) {cout << pNode->val << " " ;pNode = pNode->pNext;}cout << endl;pNode = head;cout << "\t" << "pOther指针情况:";while (pNode != NULL) {if (pNode->pOther != NULL)cout << pNode->val << "-" << pNode->pOther->val << "\t";pNode = pNode->pNext;}cout << endl;
}
int main()
{ComplexListNode* head = new ComplexListNode();ComplexListNode* node1 = new ComplexListNode();ComplexListNode* node2 = new ComplexListNode();ComplexListNode* node3 = new ComplexListNode();ComplexListNode* node4 = new ComplexListNode();head->val = 1;node1->val = 2;node2->val = 3;node3->val = 4;node4->val = 5;head->pNext = node1;	node1->pNext = node2;node2->pNext = node3;node3->pNext = node4;head->pOther = node2;node1->pOther = node3;node2->pOther = node4;cout << "复制前原始链表输出:" << endl;ShowList(head);ComplexListNode* pHead = CloneList(head);cout << "复制后原始链表输出:" << endl;ShowList(head);cout << "复制后复制链表输出:" << endl;ShowList(pHead);return 0;
}

运行结果如图所示:

 

 

 

 

 

这篇关于复杂链表的复制(随机指针)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084525

相关文章

VirtualBox中,虚拟系统文件VDI移动或者复制

在安装virtualbox以后有时需要复制,移动虚拟磁盘等操作,这些操作在vmware的虚拟机下面可以直接操作虚拟磁盘即可使用,但是在virtualbox环境 下每个VDI 文件都有一个唯一的uuid,而VirtualBox 不允许注册重复的uuid,所以直接复制的VDI文件是不能拿来使用的,我们就需要使用到virtualbox自带的管理命令来克隆一个VDI,这样通过命令克隆的VDI文件会重

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级

LeetCode--234 回文链表

题目 请判断一个链表是否为回文链表。 示例 示例 1:输入: 1->2输出: false示例 2:输入: 1->2->2->1输出: true /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val

LeetCode--206 反转链表

题目 反转一个单链表。 示例 示例:输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL class Solution {public:ListNode* reverseList(ListNode* head) {if (head == nullptr || head->next == nullptr){return head;}ListNo

剑指offer(C++)--两个链表的第一个公共结点

题目 输入两个链表,找出它们的第一个公共结点。 解法一 两个链表一定有交点的话,方法是指向短链表指针先走完,然后指向长链表,指向长链表指针后走完,指向短链表。所以,第二次走过,一定会在交点相遇。 class Solution {public:ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) {ListN

利用结构体作为函数参数时结构体指针的定义

在利用结构体作为函数的参数进行传递时,容易犯的一个错误是将一个野指针传给函数导致错误。 #include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10typedef struct {int r[MAXSIZE]; //用于存储要排序的数组,r[0]作为哨兵或者临时变量int length;

把Tiled中做出的地图弄到项目中~~就是懒,为了以后直接复制写过来

1.现在.h中声明private: cocos2d::CCSprite* ninja; cocos2d::CCTMXTiledMap*  tileMap; 然后.cpp中加入tileMap = CCTMXTiledMap::create("MyTileMap.tmx"); CCTMXLayer* backLayer = tileMap->layerNamed("Tile L

isa指针的理解

D3实例isa指向D3类对象。D3类的话isa指向D3元类对象。D3元类保存类中的方法调度列表,包括类方法和对象方法

算法6— 判断两个链表是否相交

问题: 给出两个单向链表的头指针,比如h1、h2,判断链表是否相交,如果不相交返回NULL;如果相交,返回指向第一个相交节点的指针。时间复杂度控制在O(n)。 分析: 如果两单向链表相交的话,一定是Y型相交,不可能出现X型,弄清楚这点后接下来的工作就是: (1)先找到h1,h2的最后一个节点L1和L2,同时记录节点数量a,b;(这里假设 a > b) (2)判断最后一个节点是否相同

剑指Offer—编程题56(链表中环的入口地址)

题目:一个链表中包含环,如何找出环的入口结点? 解题思路   可以用两个指针来解决这个问题。先定义两个指针P1和P2指向链表的头结点。如果链表中环有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。当第二个指针指向环的入口结点时,第一个指针已经围绕着环走了一圈又回到了入口结点。    剩下的问题就是如何得到环中结点的数目。我们在面试题15的第二个相关题目时用到