#include <iostream>
#include "LinkedList.cpp"

using namespace std;

#ifndef GRAPH_CLASS_INCLUDED
#define GRAPH_CLASS_INCLUDED

/*
	Graph Class
	LastModification : 2008. 5. 5
	Version : 0.1.0 Beta
	myllyj(myllyj at myllyj dot com) / http://program.myllyj.com

	Requirements:
		require LinkedList class.

	Comment:
		Graph´Â ÇÏ³ªÀÇ ³ëµå°¡ ¿©·¯±ºµ¥¿¡ ¿¬°á µÉ ¼ö ÀÖ¾î¾ß ÇÏ¸ç,
		¹æÇâ¼ºÀÌ Á¸Àç ÇÒ ¼öµµ ÀÖ´Ù. ¶ÇÇÑ °¢°¢ÀÇ ¸µÅ©´Â Weight¸¦
		´Þ¸® ÇÒ ¼öµµ ÀÖ´Ù.

		ÀÌ ¹öÀüÀÇ ±×·¡ÇÁ´Â Link°¡ ¹æÇâ¼ºÀ» °¡ÁöÁö ¾ÊÀ¸¸ç, LinkÀÇ
		Weight°¡ ¸ðµÎ µ¿ÀÏÇÑ °æ¿ì·Î °¡Á¤ÇÑ´Ù. ¶ÇÇÑ ÀÚ½ÅÀÌ ÀÚ½Å
		½º½º·Î¸¦ ¸µÅ© ÇÒ ¼ö ¾øÀ¸¸ç, ÀÚ½Å°ú ´Ù¸¥ ÀÎÁ¢³ëµå¿Í´Â ÇÏ³ªÀÇ
		¿¬°á¸¸ °¡Áú ¼ö ÀÖ´Ù.

		ÇöÀç ¹öÀüÀº ¾ÆÁÖ ³·Àº ½ÃÇè¹öÀüÀ¸·Î, Vertex, EdgeÀÇ ¼öÁ¤,
		»èÁ¦¸¦ Áö¿øÇÏÁö ¾Ê´Â´Ù.

*/

template <class T>
class Graph
{
private :
	LinkedList<LinkedList<T>*>* linkHolder;

public :
	Graph();
	void AddVertex(T data);
	void AddEdge(T data1, T data2);
	T GetFirstVertex();
	LinkedList<T>* GetVertics(T data);

};

template <class T>
Graph<T>::Graph()
{
	linkHolder = new LinkedList<LinkedList<T>*>;
}

// ±×·¡ÇÁ¿¡ Vertex¸¦ Ãß°¡ÇÕ´Ï´Ù.
template <class T>
void Graph<T>::AddVertex(T data)
{
	LinkedList<T>* newVertex = new LinkedList<T>();
	newVertex->AddFirst(data);
	this->linkHolder->AddLast(newVertex);
}

// ±×·¡ÇÁ¿¡ Edge¸¦ Ãß°¡ÇÕ´Ï´Ù.
template <class T>
void Graph<T>::AddEdge(T data1, T data2)
{
	bool flag = false;
	LinkedList<T>* tmpNode1;
	LinkedList<T>* tmpNode2;

	// data1¿¡ ´ëÇÑ
	this->linkHolder->MoveFirst();
	while (!linkHolder->IsHeaderNode())
	{
		tmpNode1 = linkHolder->Get();
		tmpNode1->MoveFirst();
		if (tmpNode1->Get()==data1)
		{
			flag = true;
			break;
		}
		
		linkHolder->MoveNext();
	}

	if (!flag) return;

	// data2¿¡ ´ëÇÑ
	this->linkHolder->MoveFirst();
	while (!linkHolder->IsHeaderNode())
	{
		tmpNode2 = linkHolder->Get();
		tmpNode2->MoveFirst();
		if (tmpNode2->Get()==data2)
		{
			flag = true;
			break;
		}
		
		linkHolder->MoveNext();
	}
	if (!flag) return;

	tmpNode2->AddLast(data1);
	tmpNode1->AddLast(data2);
}

// ±×·¡ÇÁ¿¡¼­ Ã¹ Vertex¸¦ Ã£½À´Ï´Ù.
template <class T>
T Graph<T>::GetFirstVertex()
{
	LinkedList<T>* tmpNode;

	linkHolder->MoveFirst();
	tmpNode = linkHolder->Get();
	tmpNode->MoveFirst();
	return tmpNode->Get();
}

// ±×·¡ÇÁ¿¡¼­ ÁöÁ¤ÇÑ Vertex¿Í ¿¬°áµÈ VertexÀÇ List¸¦ ¹ÝÈ¯ÇÕ´Ï´Ù.
template <class T>
LinkedList<T>* Graph<T>::GetVertics(T data)
{
	LinkedList<T>* tmpNode;

	linkHolder->MoveFirst();
	while (!linkHolder->IsHeaderNode())
	{
		tmpNode = linkHolder->Get();
		tmpNode->MoveFirst();
		if (tmpNode->Get()==data) return tmpNode;
		linkHolder->MoveNext();
	}

	return NULL;

}

#endif
