图 邻接表表示法
基本结构:
template<typename InfoType>
struct ArcNode
{
int adjvex;
ArcNode* nextarc;
InfoType* info;
};
template<typename VertexType, typename InfoType>
struct VNode
{
VertexType data;
ArcNode<InfoType>* firstarc;
};
template<typename VertexType, typename InfoType>
using AdjList = VNode<VertexType, InfoType>[MAX_VERTEX_NUM];
template<typename VertexType, typename InfoType>
struct ALGraph
{
AdjList<VertexType, InfoType> vertices;
int vexnum, arcnum;
GraphKind kind;
};
基本操作:
初始化
初始化图的基本数据,每个顶点的指针域置空
template<typename VertexType, typename InfoType>
Status initALGraph(ALGraph<VertexType, InfoType>& ALG, GraphKind kind)//初始化
{
for (int i = 0; i < MAX_VERTEX_NUM; i++)
ALG.vertices[i].firstarc = NULL;
ALG.kind = kind;
ALG.arcnum = 0;
ALG.vexnum = 0;
return OK;
}
查找顶点在数组中的位置
遍历所有顶点,若找到返回下标,未找到返回-1
template<typename VertexType, typename InfoType>
int indexOf(ALGraph<VertexType, InfoType>ALG, VertexType vex)//寻找vex在数组中的下标,未找到返回-1
{
for (int i = 0; i < MAX_VERTEX_NUM; i++)
{
if (vex == ALG.vertices[i].data)
return i;
}
return -1;
}
插入顶点
将新的顶点加入到顶点数组尾部
template<typename VertexType, typename InfoType>
Status insertVex_ALG(ALGraph<VertexType, InfoType>& ALG, VertexType vex)//插入顶点
{
ALG.vertices[ALG.vexnum++].data = vex;
return OK;
}
插入边
先找到源目顶点在顶点数组中的位置,然后用头插法将目的顶点的位置信息插入到源顶点指针域的第一个位置
template<typename VertexType, typename InfoType>
Status insertArc_ALG(ALGraph<VertexType, InfoType>& ALG, VertexType from, VertexType to, InfoType dist)//插入边
{
int index_f = indexOf(ALG, from);
int index_t = indexOf(ALG, to);
ArcNode<InfoType>* p = new ArcNode<InfoType>;
p->adjvex = index_t;
p->info = new InfoType(dist);
p->nextarc = ALG.vertices[index_f].firstarc;//头插法
ALG.vertices[index_f].firstarc = p;
ALG.arcnum++;
return OK;
}
创建图
从文件中读取数据,创建图,文件格式与邻接矩阵表示法相同,需要用到插入顶点和插入边的相应函数
文件格式:
vexnum arcnum
vex1 vex2 ……
vexn1 vexm1 distance
vexn2 vexm2 distance
……
template<typename VertexType, typename InfoType>
Status creatALGraph(ALGraph<VertexType, InfoType>& ALG, string fileName)//从文件创建图
{
ifstream ifs;
ifs.open(fileName);
int vexnumInFile, arcnumInFile;
ifs >> vexnumInFile >> arcnumInFile;
VertexType vex;
for (int i = 0; i < vexnumInFile; i++)
{
ifs >> vex;
insertVex_ALG(ALG, vex);
}
VertexType from, to;
InfoType dist;
for (int i = 0; i < arcnumInFile; i++)
{
ifs >> from >> to;
if (ALG.kind == UDG || ALG.kind == DG)//判断类型,图的权值均为1
dist = 1;
else//网需要赋具体的权值
ifs >> dist;
insertArc_ALG(ALG, from, to, dist);
if (ALG.kind == UDG || ALG.kind == UDN)//无向需要继续插入to到from的边
insertArc_ALG(ALG, to, from, dist);
}
return OK;
}
打印图
以邻接表的形式打印出图
template<typename VertexType, typename InfoType>
Status printALGraph(ALGraph<VertexType, InfoType>ALG)//打印图
{
ArcNode<InfoType>* p;
for (int i = 0; i < ALG.vexnum; i++)
{
cout << "[" << i << "]" << ALG.vertices[i].data;
p = ALG.vertices[i].firstarc;
while (p)
{
cout << " --> [" << p->adjvex << "]" << ALG.vertices[p->adjvex].data << "(" << *(p->info) << ")";
p = p->nextarc;
}
cout << endl;
}
return OK;
}
使用的图仍然是这个:
7 10
北京 西安 郑州 徐州 成都 广州 上海
北京 西安 2553
北京 郑州 695
北京 徐州 704
徐州 上海 651
郑州 徐州 349
西安 郑州 511
西安 成都 812
成都 广州 2368
广州 郑州 1579
广州 上海 1385