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