码迷,mamicode.com
首页 > 其他好文 > 详细

复杂链表的复制

时间:2015-10-25 22:48:21      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:复杂链表的复制

复杂链表的复制,什么是复杂链表?

   一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个random指针指向这

个链表中的一个随机节点或者NULL,现在要求实现复制这个链表,返回复制后的新链表。

复杂链表的定义:

typedef struct ComplexNode

{

DataType _data; // 数据

struct ComplexNode* _next; // 指向下一个节点的指针

struct ComplexNode* _random; // 指向随机节点

}ComplexNode;

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#define LENGTH  10//存储数据随机节点,设个数组长度,手动修改使其大于节点数
typedef int  DataType;
typedef  struct ComplexNode
{
	DataType  _data;//存储数据
	struct  ComplexNode  *_next;//下一个节点地址
	struct  ComplexNode  *_random;//随机指向的节点地址
}ComplexNode, *pComplexNode;
pComplexNode  BuyNode(DataType x);//创建节点
//尾插并初始化使节点的随机指针指向它的前一个结点
void Pushback(pComplexNode& pHead, DataType x);
void  Printf(pComplexNode pHead);//打印
void  Destory(pComplexNode&  pHead);//销毁节点
pComplexNode  CopyComplexLink(pComplexNode  pHead);//复制复杂链表
pComplexNode  BuyNode(DataType x)
{
	pComplexNode tmp = NULL;
	tmp = (pComplexNode)malloc(sizeof(ComplexNode));
	tmp->_data = x;
	tmp->_next = NULL;
	tmp->_random = NULL;
	return tmp;
}
void Pushback(pComplexNode& pHead, DataType x)
{
	pComplexNode  cur = pHead,pre=NULL;
	if (pHead == NULL)
	{
		pHead = BuyNode(x);
		pHead->_random = NULL;
	}
	else
	{
		while (cur->_next)
		{
			pre = cur;
			cur = cur->_next;
		}
		cur ->_next= BuyNode(x);
		cur->_random = pre;
		cur->_next->_random = cur;
	}
}
void  Printf(pComplexNode pHead)
{
	while (pHead)
	{
		printf("%d", pHead->_data);
		if (pHead->_random)
		{
			printf(" random:%d  ->", pHead->_random->_data);
		}
		else
			printf(" random:NULL  ->");
		pHead = pHead->_next;
	}
	printf("NULL\n");
} 
void  Destory(pComplexNode&  pHead)
{
	pComplexNode del = NULL;
	if (pHead == NULL)
		return;
	while (pHead)
	{
		del = pHead;
		pHead = pHead->_next;
		free(del);
	}
}

pComplexNode  CopyComplexLink(pComplexNode  pHead)
{
	//查找赋值法:寻找random
	//pComplexNode  tmp = NULL,sourceCur=pHead;//只复制数据和_next;
	//保存source的首地址,在复制_random中每次应从头遍历
	//pComplexNode  target = NULL,targetCur=NULL;
	//if (pHead)
	//{
	//	target = targetCur = BuyNode(pHead->_data);
	//	sourceCur = sourceCur->_next;
	//}
 //   else
	//    return  NULL;
	//while (sourceCur)
	//{
	//	tmp = BuyNode(sourceCur->_data);
	//	targetCur->_next= tmp;
	//	sourceCur = sourceCur->_next;
	//	targetCur = targetCur->_next;
	//}
	//Printf(target);//只复制数据和next的链表
	//赋值_random
	//targetCur = target;
	//sourceCur = pHead;
	//while (sourceCur&&targetCur)
	//{
	//	if (sourceCur->_random)
	//	{
	//		pComplexNode  sourceBegin = pHead,targetBegin=target;//从头找
	//		//找到random所指节点,并记录target的random所应该对应节点
	//		while (sourceBegin&&sourceBegin != sourceCur->_random&&targetBegin)
	//		{
	//			sourceBegin = sourceBegin->_next;
	//			targetBegin = targetBegin->_next;
	//		}
	//		targetCur->_random = targetBegin;
	//	}
	//	sourceCur = sourceCur->_next;
	//	targetCur = targetCur->_next;
	//}
	//return  target;

	//哈希表法
	//int  sourceRandomIndex[LENGTH] = {0};//存储原链表的随机指针指向的节点下标
	//pComplexNode  targetRandom[LENGTH] = { 0 };//全部初始化为空
	//int index = 0;
	//int count = 0;
	//memset(sourceRandomIndex, -1, LENGTH*sizeof(int));
	////复制链表的data和next,让random全指向空
	//pComplexNode  tmp = NULL,random=NULL,cur=pHead;
	//if(pHead==NULL)//空指针直接返回
	//    return  NULL;
	//while (cur)
	//{
	//	tmp = BuyNode(cur->_data);
	//	targetRandom[index] = tmp;
	//	if(cur->_random)//如果随机指针不指向空
	//	{
	//		tmp = pHead;
	//		count = 0;
	//		while (tmp&&tmp != cur->_random)
	//		{
	//			count++;
	//			tmp = tmp->_next;
	//		}
	//		if (tmp)
	//			sourceRandomIndex[index] = count;	
	//	}//如果指空,本身所存就是-1,即NULL
	//	cur = cur->_next;
	//	index++;
	//}
	//
	//index = 0;
	//for (; index < LENGTH&&targetRandom[index]; index++)
	//{
	//	//如果最后一个结点,它的下一个元素即0,初始化时为空,
	//	targetRandom[index]->_next = targetRandom[index + 1];
	//	if (sourceRandomIndex[index] == -1)
	//	{
	//		targetRandom[index]->_random = NULL;
	//	}
	//	else
	//	{
	//         	targetRandom[index]->_random	// = targetRandom[sourceRandomIndex[index]];
	//	}
	//}
	//return targetRandom[0];
	

	//将它的节点复制一份连接起来,连接后的新链表
	pComplexNode  source= pHead,tmp=NULL;
	int  count = 1;//控制奇偶,最后分离
	if (pHead == NULL)
		return NULL;
	while (source)
	{
		pComplexNode  temp = source->_next;
		tmp = BuyNode(source->_data);
		source->_next = tmp;//连接在一起
		tmp->_next = temp;
		source = tmp->_next;//跳过复制的那个
	}

	
	//复制random
	source=pHead;
	while (source)//赋值random
	{
		if (count % 2 != 0 && source->_random)//找到奇数,让它下一个的random指向它的random的下一个
			
		{
			source->_next->_random =source->_random->_next;
		}
		source=source->_next;
		count++;
	}


	//分离
	pComplexNode  target = pHead->_next;//已判定至少一个结点
	source = pHead->_next->_next;
	count = 1;//此时source是奇数位置
	pComplexNode  targetCur = target,sourceCur=pHead;
	while(source)
	{
		if (count % 2 == 0)//目标新复制链表
		{
			targetCur->_next = source;
			targetCur=targetCur->_next;
		}
		else
		{
			sourceCur->_next = source;
			sourceCur = sourceCur->_next;
		}
		source = source->_next;
		count++;
	}
	sourceCur->_next = NULL;//保证原链表分离成功
	return  target;
}
int main()
{
	pComplexNode pHead=NULL,target=NULL;
	Pushback(pHead,1);
	Pushback(pHead, 2);
	Pushback(pHead, 3);
	Pushback(pHead, 4);
	Pushback(pHead, 5);
	Pushback(pHead, 6);
	Printf(pHead);
	
	
	target=CopyComplexLink(pHead);
	Printf(target);
	

	Printf(pHead);//最后一种测试是否改变原来链表


	Destory(pHead);
	Destory(target);

	system("pause");
	return 0;
}

本人建议最好使用第三种,时间复杂度小。

本文出自 “小止” 博客,请务必保留此出处http://10541556.blog.51cto.com/10531556/1706035

复杂链表的复制

标签:复杂链表的复制

原文地址:http://10541556.blog.51cto.com/10531556/1706035

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!