经典面试题之复杂链表复制的简单实现

来源:互联网 发布:单片机最小系统图片 编辑:程序博客网 时间:2024/06/06 02:43

经典面试之复杂链表的简单实现

对于复杂链表复制问题,如果只是单纯的实现这个功能,他其实是不难的。你可以在时间空间没有要求的情况下勉强的实现它。(主要问题就在于Random指针的重新定位了)

我就简单说说那些个常规方法的繁琐实现了:

void ComplexListCopy(ComplexList &List, ComplexList &ListCopy);

1.借助于一个指针数组保存源链表的地址,然后在连接新链表之时重新遍历源链表,进行random的定位。大概的伪代码实现如下

void ComplexListCopy(ComplexList &List, ComplexList &ListCopy)
void ComplexListcopy(complexList &List,ComplexList &ListCop)
{
ComplexListNode* parr[100];
int Len = Length(List);///得到源链表长度
ComplexListNode *cur = List.head._next;//第一个
int i = 0;
//除了random,其他问题都没有;
while(cur)
{
parr[i++] = cur;
ComplexListNode *tmp = BuyNode(cur->_data);
PushBack(ListCop,tmp);
cur = cur->_next;
}

//通过遍历数组以及List确定ListCop的random连接问题
ComplexListNode *curC = ListCop.head._next;
i = 0;
while(curC)
{
ComplexListNode* tmp = List.head._next;//List 的头
int count = 0;
//找到random指向的下标数
while(tmp != parr[i])
{
tmp=tmp->_next;
}

tmp = ListCop.head._next;
while(count--)
{
curC->_randomPiont = tmp;
}
i++;
curC = curC->_next;
}
}

然而这个实在是太戳了,,浪费空间浪费时间。那么一种比较好的做法就是,不借助第三方变量,直接处在源链表中插入,然后通过相对位置处理了randomPoint 问题。这个图画的有些失败,简单说说

1上边的,,红色代表源链表,黄色为元链表中random的指向。你要做的就是,复制一个相同内容的节点插入它后边(途中黑色)

2根据相对位置处理链表中randomPoint的指向(下图中粉色的线条)
<span style="color: rgb(255, 0, 0);"></span>黑色<span style="color:#ff0000;">->_randomPoint = 红色->_randomPoint->_next;</span>

void ComplexListCopy(ComplexList &List, ComplexList &ListCopy)
cursi->_randomPoint = curdi->_randomPoint->_next;

3将红黑两个链表进行分离。


具体实现

数据类型的定义

<span style="color:#330099;">typedef int DataType;typedef struct ComplexListNode{DataType _data;struct ComplexListNode * _next;struct ComplexListNode * _randomPoint;}ComplexListNode;</span>
<span style="color:#330099;">typedef struct ComplexList{<span style="white-space:pre"></span>ComplexListNode head;}ComplexList;</span>
基本框架的搭建
void Init(ComplexList &List){List.head._data = 0;List.head._next = NULL;List.head._randomPoint = NULL;}void Destroy(ComplexList&List){ComplexListNode* cur = &List.head;while (cur){ComplexListNode *tmp = cur;cur = cur->_next;free(tmp);}}ComplexListNode* BuyNode(DataType x){ComplexListNode* ret = (ComplexListNode*)malloc(sizeof(ComplexList));if (ret == NULL)return NULL;ret->_data = x;ret->_next = NULL;ret->_randomPoint = NULL;return ret;}ComplexListNode* FindNode(ComplexList &List, DataType x){ComplexListNode* cur = List.head._next;while (cur){if (cur->_data == x)return cur;cur = cur->_next;}return NULL;}void PushFront(ComplexList &List, DataType x){ComplexListNode* tmp = BuyNode(x);tmp->_next = List.head._next;List.head._next = tmp;}
//siPos源,diPos目标void MakeComplex(ComplexList &List, DataType siData, DataType diData){<span style="white-space:pre"></span>ComplexListNode *siPos = FindNode(List, siData);<span style="white-space:pre"></span>ComplexListNode *diPos = FindNode(List, diData);<span style="white-space:pre"></span>if (siPos == NULL || diPos == NULL)<span style="white-space:pre"></span>return;<span style="white-space:pre"></span>siPos->_randomPoint = diPos;}void ShowComList(ComplexList &List){ComplexListNode* cur = List.head._next;printf("List    :");while (cur){printf("%2d -->", cur->_data);cur = cur->_next;}printf("\nListComp:");cur = List.head._next;while (cur){if (cur->_randomPoint)printf("%2d -->", cur->_randomPoint->_data);elseprintf("   -->");cur = cur->_next;}printf("\n");}

核心函数实现
void ComplexListCopy(ComplexList &List, ComplexList &ListCopy){ComplexListNode *curdi = List.head._next;//BuyNode And  Insert in List;if (curdi == NULL)return;
<span style="white-space:pre"></span>//实现插入while (curdi){ComplexListNode *tmp = BuyNode(curdi->_data);tmp->_next = curdi->_next;curdi->_next = tmp;curdi = tmp->_next;}curdi = List.head._next;ComplexListNode *cursi = curdi->_next;ListCopy.head._next = cursi;//实现对_randomPoint 指针指向的处理while (curdi&&cursi){if(curdi->_randomPoint!=NULL)cursi->_randomPoint = curdi->_randomPoint->_next;curdi = cursi->_next;if(curdi)cursi = curdi->_next;}curdi = &List.head;cursi = curdi->_next;
<span style="white-space:pre"></span>//分开两条新旧两条链表while (cursi){curdi->_next = cursi->_next;curdi = curdi->_next;cursi->_next = curdi->_next;cursi = cursi->_next;}}
以下是输出实例

对于这个复杂链表的实现问题呢,其实重点还是思路问题,即使你有一定的语言基础,也不见得能想到这里。
所以没事的时间多多联系,开拓思路还是有好处的。

void ComplexListCopy(ComplexList &List, ComplexList &ListCopy)
cursi->_randomPoint = curdi->_randomPoint->_next;
1 0
原创粉丝点击