【复杂链表】第二次OJ的总结

版权声明:转载请注明出处 https://blog.csdn.net/weixin_41238584/article/details/83055996

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_41238584/article/details/83055996