//图的函数模板之邻接表
//模板如下
//参数VexDataType是顶点元素的类型参数,ArcType是边或者弧的类型参数
template<class ArcType>
struct ArcNodeType //由边构成的链结点类型
{
int adjvex; //边的一端点
ArcType weight; //边的权
ArcNodeType *nextarc;
ArcNodeType(){nextarc = NULL;}
ArcNodeType(int node,ArcType cost);
};
template<class ArcType>
struct ArcNodeType<ArcType>::ArcNodeType(int node,ArcType cost)
{
adjvex = node; weight = cost; nextarc = NULL;
}
template<class VexDataType, class ArcType>
struct VexType //头结点类型
{
VexDataType data;
ArcNodeType<ArcType> *firstarc; //第一条边
};
template<class VexDataType, class ArcType>
class Graph
{
private:
VexType<VexDataType, ArcType> *VexList; //存放全部顶点结点
void DFSTraverse(int v, int *Visited, void (*VisitFun)(VexDataType x)); //从v号顶点开始,深度优先遍历
public:
Graph(int GraphKind,int VexSize=MaxVexNum); //GraphKind:directed or undirected
~Graph() { DestroyGraph(); }
void DestroyGraph();
int InsertArc(int v,int u, ArcType cost);
int PutVexValue(int v,VexDataType &value);
int DeleteArc(int v,int u);
void DFSTraverse(int v, void (*VisitFun)(VexDataType x));
void BFSTraverse(int v, void (*VisitFun)(VexDataType x));
};
template<class VexDataType, class ArcType>
Graph::Graph(int GraphKind,int VexSize)
{
VexNum = VexSize; GKind = GraphKind; ArcNum = 0;
VexList = new VexType<VexDataType, ArcType>[VexNum];
for(int i=0;i<VexNum;i++)
VexList[i].firstarc = NULL;
}
template<class VexDataType, class ArcType>
void Graph::DestroyGraph(void)
{
for(int i=0;i<VexNum;i++)
{
ArcNodeType<ArcType> *p = VexList[i].firstarc;
while(p)
{
ArcNodeType<ArcType> *q = p->nextarc;
delete p; p=q;
}
}
delete []VexList;
VexNum = 0; ArcNum = 0; VexList=NULL;
}
template<class VexDataType, class ArcType>
int Graph::InsertArc(int v,int u, ArcType cost)
{
if(v<0||u<0||v>=VexNum||u>=VexNum)
return 0;
ArcNodeType<ArcType> *q;
q = new ArcNodeType<ArcType>(u,cost);
q->nextarc = VexList[v].firstarc; VexList[v].firstarc = q;
if(GKind == UDGraph)
{
q = new ArcNodeType<ArcType>(v,cost);
q->nextarc = VexList[u].firstarc; VexList[u].firstarc = q;
}
ArcNum++;
return 1;
}
template<class VexDataType, class ArcType>
int Graph::PutVexValue(int v,VexDataType &value)
{
if(v>=0&&v<VexNum)
{
VexList[v].data = value;
return 1;
}
else
return 0;
}
template<class VexDataType, class ArcType>
int Graph::DeleteArc(int v,int u)
{
if(v<0||u<0||v>=VexNum||u>=VexNum)
return 0;
ArcNodeType<ArcType> *p = VexList[v].firstarc;
ArcNodeType<ArcType> *q;
int flag = 0;
if(!p) return 0;
if(p->adjvex == u) //第一条边就是要删除的边
{ VexList[v].firstarc = p->nextarc; delete p;flag = 1;}
else
{
q=p;p=p->nextarc;
while(p&&p->adjvex != u){q=p;p=p->nextarc;}
if(p) {q->nextarc= p->nextarc; delete p;flag = 1;}
}
//如果无向图,在删除另一条边
if(flag) return 1;
else return 0;
}
template<class VexDataType, class ArcType>
void Graph::DFSTraverse(int v, void (*VisitFun)(VexDataType x))
{ //公有成员函数
int* Visitd = new int[VexNum];
for(int i=0;i<VexNum; i++) Visitd[i] =0;
DFSTraverse(v, Visitd, VisitFun); //调用私有函数
delete [] Visitd;
}
template<class VexDataType, class ArcType>
void Graph::DFSTraverse(int v, int *Visited, void (*VisitFun)(VexDataType x))
{ //私有成员函数
VisitFun(GetVex(v)); Visitd[v] =1;
int u = FirstAdjVex(v);
while(u)
{
if(!Visited[u]) DFSTraverse(u, Visitd, VisitFun);
u = NextAdjVex(v, u);
}
}
template<class VexDataType, class ArcType>
void Graph::BFSTraverse(int v, void (*VisitFun)(VexDataType x))
{ //公有成员函数
int* Visitd = new int[VexNum];
for(int i=0;i<VexNum; i++) Visitd[i] =0;
VisitFun(GetVex(v)); Visitd[v] =1;
queue<int> myqueue;
myqueue.push(v);
while (!myqueue.empty())
{
v = myqueue.front();
myqueue.pop(); //遍历过就出栈不占地方
int u = FirstAdjVex(v);
while(u)
{
if(!Visited[u])
{
VisitFun(GetVex(u));
Visitd[u] =1;
myqueue.push(u);
}
u = NextAdjVex(v, u);
}
}
delete [] Visitd;
}
邻接表实现图结构的函数模板
最新推荐文章于 2022-12-10 17:03:41 发布