题目来源:http://ac.jobdu.com/problem.php?pid=1524
-
题目描述:
-
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。
-
输入:
-
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n (1<=n<=1000):n代表将要输入的链表元素的个数。(节点编号从1开始)。
接下来有n个数,表示链表节点中的值。
接下来有n个数Ti,Ti表示第i个节点的另一个指针指向。
Ti = 0 表示这个指针为NULL。
-
输出:
-
对应每个测试案例,
输出n行,每行有二个数,第一个代表当前节点值,第二个代表当前节点的特殊指针的值。
-
样例输入:
-
5 1 2 3 4 5 3 5 0 2 0
-
样例输出:
-
1 3 2 5 3 0 4 2 5 0
这题是考察细心程度的。本题可以拿空间来换取时间,但有另外一种思路,即:
(1)在每个结点N之后克隆(复制)一个结点N',并把N'链接到N的后面作为N的后继结点,先不处理其pSibling指针,处理复制节点的同时把pSilbing指针赋值为NULL。如图:
(2)现在处理每个克隆(复制)结点的pSibling指针,如若原结点N的pSibling指针指向结点S,则,N'的pSibling指针指向结点S的pNext结点。如图:
(3)现在就要把结点从原链表中拆分开来,我们可以看到奇数位是原链表中原有的结点,偶数位是克隆(复制)的结点,注意:如果带有头结点的话,pCloneHead要申请分配一个空间,其余处理与不带头结点类似。如图:
我写的是带头结点的,与上图有稍微差别,注意理解!
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Link_Node
{
int iData;
Link_Node* pNext;
Link_Node* pSibling;
Link_Node()
{
iData = 0;
pNext = pSibling = NULL;
}
};
void Clone_Node(Link_Node* pHead)
{
Link_Node* pNode = pHead->pNext;
Link_Node* pCloneNode = NULL;
while(pNode != NULL)
{
pCloneNode = new Link_Node();
pCloneNode->iData = pNode->iData;
pCloneNode->pNext = pNode->pNext;
pNode->pNext = pCloneNode;
pCloneNode->pSibling = NULL;
pNode = pCloneNode->pNext;
}
}
void ConnectSiblingNode(Link_Node* pHead)
{
Link_Node* pNode = pHead->pNext;
Link_Node* pCloneNode = NULL;
while(pNode != NULL)
{
pCloneNode = pNode->pNext;
if(pNode->pSibling != NULL)
pCloneNode->pSibling = pNode->pSibling->pNext;
pNode = pCloneNode->pNext;
}
}
Link_Node* ReConnetCloneLink(Link_Node* pHead)
{
Link_Node* pNode = pHead->pNext;
Link_Node* pCloneHead = new Link_Node();
Link_Node* pCloneNode = pNode->pNext;
pCloneHead->pNext = pCloneNode;
if(pNode != NULL)
{
pCloneNode = pNode->pNext;
pNode->pNext = pCloneNode->pNext;
pNode = pNode->pNext;
}
while(pNode != NULL)
{
pCloneNode->pNext = pNode->pNext;
pCloneNode = pCloneNode->pNext;
pNode->pNext = pCloneNode->pNext;
pNode = pNode->pNext;
}
return pCloneHead;
}
void Delete_Link(Link_Node* pHead)
{
Link_Node* p1 = pHead;
Link_Node* p2 = NULL;
while(p1 != NULL)
{
p2 = p1->pNext;
delete p1;
p1 = p2;
}
}
void Print_CloneLink(Link_Node* pHead)
{
Link_Node* pNode = pHead->pNext;
while(pNode != NULL)
{
printf("%d", pNode->iData);
if(pNode->pSibling != NULL)
printf(" %d\n", pNode->pSibling->iData);
else
printf(" 0\n");
pNode = pNode->pNext;
}
Delete_Link(pHead);
}
void Clone_Link(Link_Node* pHead)
{
Clone_Node(pHead);
ConnectSiblingNode(pHead);
Print_CloneLink(ReConnetCloneLink(pHead));
}
int main()
{
int n, i, a;
Link_Node* pHead;
while(~scanf("%d", &n))
{
pHead = new Link_Node();
Link_Node* p1 = pHead;
Link_Node* pNode = NULL;
for(i = 0; i < n; ++i)
{
pNode = new Link_Node();
scanf("%d", &a);
pNode->iData = a;
p1->pNext = pNode;
p1 = pNode;
}
p1 = pHead->pNext;
Link_Node* p2 = p1;
for(i = 0; i < n; ++i)
{
scanf("%d", &a);
if(a == 0)
p1->pSibling = NULL;
else
{
while(a > 1)
p2 = p2->pNext, --a;
p1->pSibling = p2;
p2 = pHead->pNext;
}
p1 = p1->pNext;
}
Clone_Link(pHead);
Delete_Link(pHead);
}
return 0;
}