数据结构-----复杂链表复制

本文介绍了一种复杂链表的复制方法,该链表除了包含指向下一个节点的指针外,还有一个指向链表中任意节点的随机指针。文章详细阐述了如何通过三步完成链表的深拷贝:首先复制并插入每个节点;其次复制随机指针;最后将链表拆分为原链表和新链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//复杂链表的复制
#pragma once

#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

typedef struct ComplexNode {
	int	data;
	struct ComplexNode	*pNext;
	struct ComplexNode	*pRandom;
}	CN;


CN	* Copy(CN *pFirst)
{
	CN	*pNode;
	CN	*pNewNode;
	CN	*pOldRandom;
	CN	*pNewRandom;

	// 1. 复制结点,放到老结点后边
	for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext->pNext) {
		pNewNode = (CN *)malloc(sizeof(CN));
		assert(pNewNode);
		pNewNode->data = pNode->data;
		pNewNode->pRandom = NULL;

		pNewNode->pNext = pNode->pNext;
		pNode->pNext = pNewNode;
	}

	// 2. 复制 pRandom
	for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext->pNext) {
		pNewNode = pNode->pNext;
		pOldRandom = pNode->pRandom;
		if (pOldRandom != NULL) {
			pNewRandom = pOldRandom->pNext;
			pNewNode->pRandom = pNewRandom;
		}
	}

	//	3. 拆链表
	CN	*pNewFirst = pFirst->pNext;
	for (pNode = pFirst; pNode != NULL; pNode = pNode->pNext) {
		pNewNode = pNode->pNext;

		pNode->pNext = pNewNode->pNext;
		if (pNode->pNext != NULL) {
			pNewNode->pNext = pNode->pNext->pNext;
		}
		else {
			pNewNode->pNext = NULL;
		}
	}

	return pNewFirst;
}

CN	* Buy(int data)
{
	CN	*pNode = (CN *)malloc(sizeof(CN));
	assert(pNode);
	pNode->data = data;
	pNode->pRandom = NULL;
	pNode->pNext = NULL;

	return pNode;
}

void Print(CN *pFirst)
{
	CN	*pNode;
	for (pNode = pFirst; pNode; pNode = pNode->pNext) {
		printf("[%d, (%p, %d)] ",
			pNode->data,
			pNode->pRandom,
			pNode->pRandom ? pNode->pRandom->data : 0);
	}
	printf("\n");
	printf("pFisrt:[%d,(%p, %d)]",
		pFirst->data,
		pFirst->pRandom,
		pFirst->pRandom ? pFirst->pRandom->data : 0);
}

void TestCN()
{
	CN	*p1 = Buy(1);
	CN	*p2 = Buy(2);
	CN	*p3 = Buy(3);
	CN	*p4 = Buy(4);

	p1->pNext = p2;
	p2->pNext = p3;
	p3->pNext = p4;

	p1->pRandom = p4;
	p4->pRandom = p1;
	p2->pRandom = p2;

	//Print(p1);

	CN	*pNew = Copy(p1);

	Print(pNew);
}



//在牛客网的oj环境下编译通过的
//void CloneRandom(RandomListNode* pHead){
//	RandomListNode* pCloned;
//	while (pHead != NULL){
//		pCloned = pHead->next;
//		if (pHead->random != NULL){
//			pCloned->random = pHead->random->next;
//		}
//		pHead = pCloned->next;
//	}
//}
//
//RandomListNode* ReConnectNodes(RandomListNode* pHead){
//	RandomListNode* pClonedHead = NULL;
//	RandomListNode* pClonedNode = NULL;
//	RandomListNode* pNode = pHead;
//
//	if (pNode != NULL){
//		pClonedHead = pClonedNode = pNode->next;
//		pNode->next = pClonedNode->next;
//		pNode = pNode->next;
//	}
//
//	while (pNode != NULL){
//		pClonedNode->next = pNode->next;
//		pClonedNode = pClonedNode->next;
//		pNode->next = pClonedNode->next;
//		pNode = pNode->next;
//	}
//	return pClonedHead;
//}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值