|
|
|
|
|
#pragma once
|
|
|
|
|
|
#include <list>
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
|
|
* Version : 1.0
|
|
|
|
|
|
* Date : 09 Jun 2017
|
|
|
|
|
|
* Description: ͼģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
/************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
|
class TGraphNode
|
|
|
|
|
|
{
|
|
|
|
|
|
public://methods
|
|
|
|
|
|
inline TGraphNode(): mark(0){}
|
|
|
|
|
|
inline ~TGraphNode(){}
|
|
|
|
|
|
inline void SetValue(const T& val) { value = val; }
|
|
|
|
|
|
inline T& GetValue(void) {return value;}
|
|
|
|
|
|
inline void SetMark(int mk) {mark = mk; }
|
|
|
|
|
|
inline int GetMark(void) {return mark; }
|
|
|
|
|
|
list<TGraphNode*>& GetPrev(void) {return m_prevNodes; }
|
|
|
|
|
|
list<TGraphNode*>& GetNext(void) {return m_nextNodes; }
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>
|
|
|
|
|
|
inline void ClearPrev(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_prevNodes.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>к<EFBFBD><D0BA><EFBFBD>
|
|
|
|
|
|
inline void ClearNext(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_nextNodes.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
inline bool AddPrevNode(TGraphNode* pNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(0 == pNode)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
if(find( GetPrev().begin(),GetPrev().end(),pNode ) != GetPrev().end() )
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
this->GetPrev().push_back(pNode);
|
|
|
|
|
|
pNode->GetNext().push_back(this);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD><CCBD><EFBFBD>
|
|
|
|
|
|
inline bool AddNextNode(TGraphNode* pNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(0 == pNode)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
if(find( GetNext().begin(),GetNext().end(),pNode ) != GetNext().end() )
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
this->GetNext().push_back(pNode);
|
|
|
|
|
|
pNode->GetPrev().push_back(this);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F>ý<EFBFBD><C3BD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
inline bool hasLinkedNodes(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(GetNext().empty() && GetPrev().empty() )
|
|
|
|
|
|
return false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//members
|
|
|
|
|
|
private:
|
|
|
|
|
|
T value; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
int mark; //<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
|
list<TGraphNode*> m_prevNodes; // ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>list
|
|
|
|
|
|
list<TGraphNode*> m_nextNodes; //<2F><><EFBFBD>̽<EFBFBD><CCBD><EFBFBD>list
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
|
class TGraph
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
inline TGraph(void) {}
|
|
|
|
|
|
inline ~TGraph(void) {DeepErase();}
|
|
|
|
|
|
//<2F><><EFBFBD>ս<EFBFBD><D5BD><EFBFBD>
|
|
|
|
|
|
inline void Clear(void){m_graphNodes.clear(); }
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
inline void DeepErase(void)
|
|
|
|
|
|
{
|
|
|
|
|
|
//m_graphNodes.sort();
|
|
|
|
|
|
//m_graphNodes.unique();
|
|
|
|
|
|
typename list<TGraphNode<T>* >::iterator iter;
|
|
|
|
|
|
for(iter = m_graphNodes.begin(); iter != m_graphNodes.end(); iter ++ )
|
|
|
|
|
|
delete *iter;
|
|
|
|
|
|
|
|
|
|
|
|
m_graphNodes.clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>½<EFBFBD><C2BD><EFBFBD>
|
|
|
|
|
|
inline void AddNode(TGraphNode<T>* pNode, list<TGraphNode<T>*>* plstPrev = 0, list<TGraphNode<T>*>* plstNext = 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_graphNodes.push_back(pNode);
|
|
|
|
|
|
|
|
|
|
|
|
if(0 == plstPrev && 0 == plstNext)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
SetLink(pNode,plstPrev,plstNext);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD>ϵ
|
|
|
|
|
|
inline void SetLink(TGraphNode<T>* pNode, list<TGraphNode<T>*>* plstPrev , list<TGraphNode<T>*>* plstNext)
|
|
|
|
|
|
{
|
|
|
|
|
|
typename list<TGraphNode<T>*>::iterator iter;
|
|
|
|
|
|
if(0 != plstPrev)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
for(iter = plstPrev->begin(); iter != plstPrev->end(); iter ++ )
|
|
|
|
|
|
(*iter)->AddNextNode(pNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
if(0 != plstNext)
|
|
|
|
|
|
{
|
|
|
|
|
|
for(iter = plstNext->begin(); iter != plstNext->end(); iter ++ )
|
|
|
|
|
|
(*iter)->AddPrevNode(pNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
inline int GetCount(void) {return m_graphNodes.size(); }
|
|
|
|
|
|
////<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>жϺ<D0B6><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٳ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>״<EFBFBD><D7B4>·
|
|
|
|
|
|
//inline bool TraceCircle(TGraphNode<T>* pStart, list<TGraphNode<T>* >& dstCircle, (TGraphNode<T>*)Fun_NextNode(TGraphNode<T>* pLast,TGraphNode<T>* pCurrent) )
|
|
|
|
|
|
//{
|
|
|
|
|
|
// dstCircle.push_back(pStart);
|
|
|
|
|
|
// TGraphNode<T>* pLast = 0;
|
|
|
|
|
|
// TGraphNode<T>* pCurrent = pStart;
|
|
|
|
|
|
// while(pCurrent = Fun_NextNode(pLast,pCurrent) )
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if(pCurrent == pStart)
|
|
|
|
|
|
// return true;
|
|
|
|
|
|
// dstCircle.push_back(pCurrent);
|
|
|
|
|
|
|
|
|
|
|
|
// if(dstCircle.size() > m_graphNodes.size()+1)
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
list<TGraphNode<T>* > m_graphNodes; //<2F>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|