复杂链表的复制

题目:实现函数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;
}

结果:


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Unity中,如果你想要复制一个复杂的数据结构,如链表(通常在脚本中用自定义的Node类实现),你需要逐个节点地复制,并确保子节点和指针也被正确复制。这里是一个简化的步骤: 1. **定义节点类** (如果尚未存在): ```csharp public class Node<T> { public T data; public Node<T> next; // 其他可能的属性或方法... } ``` 2. **复制链表头结点**: 创建一个新的`Node`实例,将原始头结点的数据复制过去,然后设置新的头结点的`next`为复制后的`Node`。 ```csharp Node<T> newNode = new Node<T>(); newNode.data = originalHead.data; newNode.next = null; // 初始化新节点的next为null ``` 3. **递归复制链表**: 使用递归函数来遍历原链表,对于每个节点,复制其数据并更新新链表中的下一个节点指向新复制的节点。 ```csharp public Node<T> CloneNode(Node<T> node, Node<T> clonedNode) { if (node != null) { clonedNode.data = node.data; clonedNode.next = CloneNode(node.next, clonedNode.next); // 递归处理下一个节点 } return clonedNode; } Node<T> clonedHead = CloneNode(originalHead, newNode); ``` 4. **处理复杂节点**: 如果链表中的节点包含更复杂的对象,比如数组、列表等,你也需要递归地复制这些内容。 5. **检查和连接**: 完成复制后,确保新链表的最后一个节点的`next`指向原链表的最后一个节点,以保证连接完整。 ```csharp if (clonedHead.next == null) // 如果新链表不为空,连接最后两个节点 { clonedHead.next = originalHead.next; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值