2018/10/15
问题描述
一般链表中,每个结点会有一个Next指针指向下一个结点,而复杂链表则还有一个Random指针指向链表中的任意一个结点或者NULL。一个复杂链表结点的C++定义如下:
struct ComplexNode
{
int Value;
ComplexNode* Next;
ComplexNode* Random;
};
输入格式
题目的输入总共有5行,同学们需要构建一个包含N个结点的头结点不为空的复杂链表并完成相应操作,我们定义从头结点到尾结点依次为第0个结点到第N-1个结点。
第一行包含4个整数。分别为N(链表结点个数), M(需要删除的结点个数), K(需要插入的结点个数)和目标结点的索引T(与输出有关,-1<T<N-M+K,T为整数)。
第二行包含N个整数。依次为第0个结点到第N-1结点的值。
第三行包含N个整数,依次为第0个结点到第N-1个结点的Random指针指向结点的索引。注意,若第X个整数为-1则说明第X-1个结点的Random指针指向NULL。
第四行包含M个整数,依次为需要删除的结点在当前链表中的索引。注意,所有指向这些被删除结点的指针在结点删除后都应该指向NULL。每删除一个结点,则更新一次链表。
第五行包含3K个整数,三个数为一组。每一组中的第一个整数为待插入结点的值,第二个整数为待插入结点在当前链表中插入后的索引,第三个整数为待插入结点在当前链表中插入后Random指向结点的索引(第三个整数为-1代表待插入结点的Random指针指向NULL)。每一个结点插入当前链表后,更新当前链表。
复杂链表操作示例:
对于形同输入样例的输入,首先根据前三行数据信息建立复杂链表如下:
随后按照输入的第四行删除链表中的M个结点:
最后按照输入的第五行依次插入K个结点:
如此,就完成了复杂链表的构建、删除和插入操作。
输入数据范围:每一个结点的值在区间[-20,20]内,0<N<20000,0<M<1000,0<K<1000
输出格式
输出包含两行。
第一行:从目标结点T开始,通过Next指针访问链表,依次输出各结点的值,直到某一结点Next指针指向NULL,则输出-1结尾。
第二行:从目标结点T开始,通过Random指针访问链表,依次输出各结点的值,直到某一结点Random指针指向NULL,则输出-1结尾。
输入样例
5 2 2 0
3 1 6 9 15
2 4 -1 1 -1
2 3
1 0 2 10 3 -1
输出样例
1 3 1 10 9 -1
1 1 -1
没有什么难度,适合用来熟悉链表。
源代码如下 :
#include <stdio.h>
struct ComplexNode{
int Value;
ComplexNode *Next;
ComplexNode *Random;
};
class ComplexLinkList{
public:
ComplexLinkList(){ Head = NULL;}
~ComplexLinkList(){};
bool RandOrient(int location,int target);
bool Insert(int location,int value);
bool Delete(int location);
bool Traverse(int target);
bool RandTraverse(int target);
private:
ComplexNode *Head;
};
bool ComplexLinkList::RandOrient(int location,int target){
ComplexNode *p = Head,*s = Head;
int i=0,j=0;
while(p && i<location){
p = p->Next;
++i;
}
if(p == NULL) return false;
if(target == -1){
p->Random = NULL;
return true;
}
else{
while(s && j<target){
s = s->Next;
++j;
}
if(s == NULL) return false;
p->Random = s;
}
return true;
}
bool ComplexLinkList::Insert(int location,int value){
ComplexNode *p = Head,*s;
int j=0;
if(!location){
s = (ComplexNode *)new ComplexNode[1];
s->Value = value;
s->Next = p;
Head = s;
return true;
}
while(p && j<location-1){
p = p->Next;
++j;
}
if(!p) return false;
s = (ComplexNode *)new ComplexNode[1];
s->Value = value;
s->Next = p->Next;p->Next = s;
return true;
}
bool ComplexLinkList::Delete(int location){
ComplexNode *p = Head,*q = Head,*s;
int j=0;
if(!p) return false;
if(!location){
Head = Head->Next;
delete p;p = NULL;
return true;
}
while(p->Next && j<location-1){
p = p->Next;
++j;
}
if(!(p->Next) || j>location-1) return false;
s = p->Next;
while(q->Next){
if(q->Random == s) q->Random = NULL;
q = q->Next;
}
p->Next = s->Next;
delete s;s = NULL;
return true;
}
bool ComplexLinkList::Traverse(int target){
ComplexNode *p = Head;
int j=0;
while(p && j<target){
p = p->Next;
++j;
}
if(p == NULL) return false;
while(p){
printf("%d ",p->Value);
p = p->Next;
}
printf("-1\n");
return true;
}
bool ComplexLinkList::RandTraverse(int target){
ComplexNode *p = Head;
int j=0;
while(p && j<target){
p = p->Next;
++j;
}
if(p == NULL) return false;
while(p){
printf("%d ",p->Value);
p = p->Random;
}
printf("-1\n");
return true;
}
int main(){
ComplexLinkList *list = new ComplexLinkList();
int i;
int Num_Node,Num_Delete,Num_Insert,Serial_Begin;
scanf("%d",&Num_Node);scanf("%d",&Num_Delete);scanf("%d",&Num_Insert);scanf("%d",&Serial_Begin);
int *Value_Node = new int[Num_Node];
int *Random_Node = new int[Num_Node];
int *Delete_Node = new int[Num_Delete];
int *Insert_Node = new int[3*Num_Insert];
for(i=0;i<Num_Node;++i) scanf("%d",&Value_Node[i]);
for(i=0;i<Num_Node;++i) scanf("%d",&Random_Node[i]);
for(i=0;i<Num_Delete;++i) scanf("%d",&Delete_Node[i]);
for(i=0;i<3*Num_Insert;++i) scanf("%d",&Insert_Node[i]);
for(i=0;i<Num_Node;++i) list->Insert(i,Value_Node[i]);
delete []Value_Node;Value_Node = NULL;
for(i=0;i<Num_Node;++i) list->RandOrient(i,Random_Node[i]);
delete []Random_Node;Random_Node = NULL;
for(i=0;i<Num_Delete;++i) list->Delete(Delete_Node[i]);
delete []Delete_Node;Delete_Node = NULL;
for(i=0;i<3*Num_Insert;i+=3){
list->Insert(Insert_Node[i+1],Insert_Node[i]);
list->RandOrient(Insert_Node[i+1],Insert_Node[i+2]);
}
delete []Insert_Node;Insert_Node = NULL;
list->Traverse(Serial_Begin);
list->RandTraverse(Serial_Begin);
return 0;
}