题目:实现函数complextListNode* clone(ComplexListNoe* pHead),复制一个链表。
在复制链表中,每一个节点除了有一个m_pNext指针指向向下一个节点外,还有一个
指针m_pSibling指向链表中的任意节点或者NULL
节点定义如下:
struct ComplexListNode
{
int m_nValue;
ComplexLstNode* m_pNext;
ComplexListNode* m_pSibling;
};
思想:
空间换时间。
第一步:
根据原始链表的每一个节点N创建对应的N‘。这一次,把N’连接在N的后面
第二步:
设置复制出来的节点的m_pSibling。假设原始链表上的N的m_pSibling指向的
节点是S,那么其对应复制出来的N‘是N的m_pNext指向的节点。同样S’是S的m_pNext指向
的节点
第三步:
把这个长链表拆分成两个链表,奇数位置的节点用m_pNext连接起来就是
原始链表,把偶数节点用m_pNext连接起来就是复制出来 的链表
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
} ;
//第一步 复制链表节点
void cloneNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode = pHead;
while(pNode!=NULL)
{
ComplexListNode* pCloned =(ComplexListNode*)malloc(sizeof(ComplexListNode));
pCloned->m_nValue=pNode->m_nValue;
pCloned->m_pNext=pNode->m_pNext;
pCloned->m_pSibling=NULL;//复制刚开始m_pSibling设置为NULL
pNode->m_pNext=pCloned;
pNode = pCloned->m_pNext;
}
}
//第二步 连接兄弟节点
void connextSiblingNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode=pHead;
while(pNode!=NULL)
{
ComplexListNode* pCloned =pNode->m_pNext;
if(pNode->m_pSibling!=NULL)
{
pCloned->m_pSibling=pNode->m_pSibling->m_pNext;
pNode=pCloned->m_pNext;
}
}
}
//第三步 分解链表 奇数节点是原链表节点 偶数节点构成新链表节点
ComplexListNode* reconnectNodes(ComplexListNode* pHead)
{
ComplexListNode* pNode=pHead;
ComplexListNode* pClonedHead=NULL;//新链表的头结点
ComplexListNode* pClonedNode=NULL;
if(pNode!=NULL)
{
pClonedHead=pClonedNode=pNode->m_pNext;
pNode->m_pNext=pClonedNode->m_pNext;
pNode=pNode->m_pNext;
}
while(pNode!=NULL)
{
pClonedNode->m_pNext=pNode->m_pNext;
pClonedNode=pClonedNode->m_pNext;
pNode->m_pNext=pClonedNode->m_pNext;
pNode=pNode->m_pNext;
}
return pClonedHead;
}
//三步结合起来
ComplexListNode* clone(ComplexListNode* pHead)
{
cloneNodes(pHead);
connextSiblingNodes(pHead);
return reconnectNodes(pHead);
}
//打印链表
void printList(ComplexListNode* pHead)
{
ComplexListNode* pCur=pHead;
while(pCur)
{
printf("%d",pCur->m_nValue);
if(pCur->m_pSibling)
{
printf("%d\n",pCur->m_pSibling->m_nValue);
}
else
{
printf("0\n");
}
pCur=pCur->m_pNext;
}
printf("\n");
}
//创建链表
ComplexListNode* createList()
{
int nLen=0;
int nSiblingData=0;//兄弟节点的结点值
scanf("%d",&nLen);
ComplexListNode* pHead=NULL;
ComplexListNode* pNew=NULL;
ComplexListNode* pLast=NULL;
for(int i=0;i<nLen;i++)
{
pNew=(ComplexListNode*)malloc(sizeof(ComplexListNode));
scanf("%d",&pNew->m_nValue);
pNew->m_pNext=NULL;
pNew->m_pSibling=NULL;
if(pHead==NULL)
pHead=pNew;
else
pLast->m_pNext=pNew;
pLast=pNew;
}
ComplexListNode* pCur=pHead;
ComplexListNode* pCurTmp=pHead;
while(pCur)
{
scanf("%d",&nSiblingData);
pCurTmp=pHead;
if(nSiblingData==0)
pCur->m_pSibling=NULL;
else
{
while(pCurTmp&&nSiblingData!=pCurTmp->m_nValue)
pCurTmp=pCurTmp->m_pNext;
assert(pCurTmp);
pCur->m_pSibling=pCurTmp;
}
pCur=pCur->m_pNext;
}
return pHead;
}
int main()
{
ComplexListNode* pHead=NULL;
ComplexListNode* pNewHead=NULL;
pHead=createList();
printList(pHead);
pNewHead = clone(pHead);
printList(pHead);
return 0;
}
结果:
分享到:
相关推荐
【部分内容】:这段代码提供了一个解决复杂链表复制问题的算法,具体分为以下三个步骤: 1. 克隆节点并连接到原节点后面:遍历链表,对于每个节点,创建一个新的克隆节点,并将其插入到原节点之后。这样,新旧两个...
《复杂链表的复制》是编程...总的来说,解决复杂链表复制的问题,关键在于理解链表结构和巧妙地利用复制节点的相邻关系来简化操作。这种问题在面试中经常出现,有助于考察候选人的思维灵活性和对数据结构的掌握程度。
复杂链表的复制问题是一个经典的深度优先搜索(DFS)或广度优先搜索(BFS)问题,主要涉及链表操作和内存管理。题目要求我们复制一个具有额外随机指针的链表,其中每个节点不仅有指向下一个节点的指针,还可能有一个...
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会...
python 实现 复杂链表的复制
C语言之复杂链表的复制方法详解 一、什么是复杂链表? 复杂链表是一种特殊的链表结构,它的每个结点不仅有一个指向下一个节点的指针,还有一个随机指针域,该指针域可以指向链表中的任意一个节点或为空结点。这种...
java基础面试题复杂链表的复制本资源系百度网盘分享地址
c++ c++_剑指offer题解之复杂链表的复制
python python_剑指offer第25题复杂链表的复制
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的 深拷贝。 我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, ...
剑指 Offer 35. 复杂链表的复制标签:哈希表、链表难度:中等题目大意给定一个链表,每个节点除了 next 指针之后,还包含一个随机指针 random,该
1、遍历链表,复制每个结点,如复制结点A得到A1,将结点A1插到结点A后面 2、重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.ran
剑指Offer(Python多种思路实现):复杂链表的复制 面试35题: 题目:复杂链表的复制 题:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为...
复制复杂链表的核心在于处理随机指针。一种常见的方法是创建一个新的链表,其节点的随机指针暂时都为空,然后将新旧链表合并,使新链表的每个节点紧随原链表的对应节点。在合并的链表中,新链表的每个节点的随机指针...
所以,我们需要在一开始把所有的节点都创建出来,避免 random 找不到指向,每个节点都对应着一个新的节点,原链表中的节点有 val、next、random 三
# Python实现《剑指offer》 部分代码自己添加了一些测试用例, 或者自己添加了一些功能 1. 初级程序员注重算法和数据结构 2. 事先做好准备,对工作有热情 3. 面试过程放松。不要急于写代码,了解清楚所要解决的问题,...
主要介绍了Java面试题-实现复杂链表的复制代码分享,小编觉得还是挺不错的,具有参考价值,需要的朋友可以了解下。
11. **赋值**:链表的赋值操作通常涉及复制另一个链表的所有节点,实现链表内容的复制。 以上这些功能的实现都需要对C++的指针操作有深入理解,同时,由于链表的动态特性,它在内存管理上比静态数据结构如数组更为...
7. **复杂链表的深度拷贝**:创建链表的深拷贝,不仅要复制节点数据,还要复制所有的子节点,这涉及到递归操作。 每个问题都提供了详细的解题思路和代码实现,通过实践和比较不同的解法,可以帮助学习者深入理解...