1. 程式人生 > >【複雜連結串列】第二次OJ的總結

【複雜連結串列】第二次OJ的總結

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