标签:复杂链表的复制
复杂链表的复制,什么是复杂链表?
一个链表的每个节点,有一个指向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