本文章参考https://blog.csdn.net/nichengwuxiao/article/details/78911896
、
图的表示最长用的两种方法是:邻接矩阵表示法
邻接表表示
按邻接矩阵进行实现:
CreateGraph.h
#include<iostream>
#include<vector>
using namespace std;
//枚举类型,图的种类 DG:有向图;WDG:带权值的有向图;
//UDG: 无向图;WUDG: 带权值的无向图
enum GraphKind{DG,WDG,UDG,WUDG};
template<typename VertexType,typename VRType,typename InfoType>
class MGraph
{
public:
MGraph(int vexNum, GraphKind __kind) :vexnum(vexNum), arcnum(0), kind(__kind)
{
vvec = new VertexType[vexnum];
arcs = new ArcCell *[vexnum];//二维数组动态分配(vexnum*vexnum)
for (int i = 0; i < vexnum; i++)
{
arcs[i] = new ArcCell[vexnum];
}
}
void Create()
{
switch (kind)
{
case DG:
CreateDG();
break;
case WDG:
CreateWDG();
break;
case UDG:
CreateUDG();
break;
case WUDG:
CreateWUDG();
break;
default:
return;
}
}
void Init()
{
cout << "请输入每个顶点的关键字:" << endl;
VertexType val;
for (int i = 0; i < vexnum; i++)
{
cin >> val;
vvec[i] = val;
}
for (int i = 0; i < vexnum; i++)
{
ArcCell ac;
ac.adj = 0;
ac.info = NULL;
for (int j = 0; j < vexnum; j++)
arcs[i][j] = ac;
}
}
void CreateDG()//构造一个有向图
{
Init();
int vhead, vtail;
cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
while (cin >> vhead >> vtail)
{
arcnum++;
arcs[vhead][vtail].adj = 1;
}
}
void CreateWDG()//构造一个带权有向图
{
Init();
int vhead, vtail;
InfoType w;
cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
while (cin >> vhead >> vtail >> w)
{
arcnum++;
arcs[vhead][vtail].adj = w;
}
}
void CreateUDG()//构造一个无向图
{
Init();
int vhead, vtail;
cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
while (cin >> vhead >> vtail)
{
arcnum += 2;
arcs[vhead][vtail].adj = 1;
arcs[vtail][vhead].adj = 1;
}
}
void CreateWUDG()//构造一个带权无向图
{
Init();
int vhead, vtail;
InfoType w;
cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
while (cin >> vhead >> vtail>>w)
{
arcnum += 2;
arcs[vhead][vtail].adj = w;
arcs[vtail][vhead].adj = w;
}
}
void displayGraph()
{
cout << "总共有" << vexnum << "个顶点," << arcnum << "条边" << endl;
for (int i = 0; i < vexnum; i++)
{
cout << "第" << i + 1 << "个顶点是:" << vvec[i] << "相邻的边有:";
for (int j = 0; j < vexnum; j++)
{
if (arcs[i][j].adj != 0)
cout << vvec[j] << "(" << arcs[i][j].adj << ")";
}
cout << endl;
}
}
private:
struct ArcCell
{
VRType adj;//两连接点之间的权值
InfoType info;
};
VertexType *vvec;//顶点向量
ArcCell **arcs;//邻接矩阵
int vexnum;//图的结点个数
int arcnum;//图的边的个数
GraphKind kind;//图的种类
};
main.cpp
#include<iostream>
#include"CreateGraph.h"
using namespace std;
int main()
{
cout << "请输入一个整数,选择构建图的类型:" << endl;
cout << "1、构造无向图" << endl;
cout << "2、构造带权无向图" << endl;
cout << "3、构造有向图" << endl;
cout << "4、构造带权有向图" << endl;
int ch;
cin>>ch;
switch (ch)//如果要在case里面定义变量,需要用括号括起来{}
{
case 1:
{
cout << "构造无向图:" << endl;
MGraph<char, int, int> udgGraph(8, UDG);
udgGraph.Create();
udgGraph.displayGraph();
break;
}
case 2:
{
cout << "构造带权无向图:" << endl;
MGraph<char, int, int> wudgGraph(9, WUDG);
wudgGraph.Create();
wudgGraph.displayGraph();
break;
}
case 3:
{
cout << "构造有向图:" << endl;
MGraph<char, int, int> dgGraph(6, DG);
dgGraph.Create();
dgGraph.displayGraph();
break;
}
case 4:
{
cout << "构造带权有向图:" << endl;
MGraph<char, int, int> wdgGraph(6, WDG);
wdgGraph.Create();
wdgGraph.displayGraph();
break;
}
}
system("pause");
return 0;
}
结果为:
按邻接表进行实现:
CreateGraph.h
#pragma once
#include<iostream>
using namespace std;
enum GraphKind{DG,WDG,UDG,WUDG};
template<typename VertexType,typename InfoType>
class ALGraph
{
public:
static const int MAX_VERTEX_NUM = 20;
ALGraph(int verNum, GraphKind _kind)
:vexnum(verNum), arcnum(0), kind(_kind)
{
for (int i = 0; i < MAX_VERTEX_NUM; i++)//初始化
vertices[i].firstarc = NULL;
}
void Create()
{
switch (kind)
{
case DG://构造一个有向图
CreateDG();
break;
case WDG://构造一个带权有向图
CreateWDG();
break;
case UDG://构造一个无向图
CreateUDG();
break;
case WUDG://构造一个带权无向图
CreateWUDG();
break;
}
}
void displayGraph()
{
for (int i = 0; i < vexnum; i++)
{
cout << "第" << i + 1 << "个顶点是:" << vertices[i].data
<< "邻接表为:";
ArcNode *arcNode = vertices[i].firstarc;
while (arcNode)
{
cout << "->" << vertices[arcNode->adjvex].data
<< "(" << arcNode->info << ")";
arcNode = arcNode->nextarc;
}
cout << endl;
}
}
private:
void InitVertics()//初始化头列表
{
cout << "请输入每个顶点的关键字:" << endl;
VertexType val;
for (int i = 0; i < vexnum; i++)
{
cin >> val;
vertices[i].data = val;
}
}
void insertArc(int vHead, int vTail, InfoType w)
{
ArcNode *newArcNode = new ArcNode;
newArcNode->adjvex = vTail;
newArcNode->nextarc = NULL;
newArcNode->info = w;
ArcNode *arcNode = vertices[vHead].firstarc;
if (NULL == arcNode)
vertices[vHead].firstarc = newArcNode;
else
{
while (arcNode->nextarc != NULL)
{
arcNode = arcNode->nextarc;
}
arcNode->nextarc = newArcNode;
}
arcnum++;
}
//构造一个有向图
void CreateDG()
{
InitVertics();
int vhead, vtail;
cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
while (cin >> vhead >> vtail)
{
insertArc(vhead, vtail, 0);
}
}
//构造一个带权有向图
void CreateWDG()
{
InitVertics();
int vhead, vtail;
InfoType w;
cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
while (cin >> vhead >> vtail >> w)
{
insertArc(vhead, vtail, w);
}
}
//构造一个无向图
void CreateUDG()
{
InitVertics();
int vhead, vtail;
cout << "请依次输入每条边的开始顶点和结束顶点:" << endl;
while (cin >> vhead >> vtail)
{
insertArc(vhead, vtail, 0);
insertArc(vtail, vhead, 0);
}
}
//
void CreateWUDG()
{
InitVertics();
int vhead, vtail;
InfoType w;
cout << "请依次输入每条边的开始顶点和结束顶点和权值:" << endl;
while (cin >> vhead >> vtail>>w)
{
insertArc(vhead, vtail, w);
insertArc(vtail, vhead, w);
}
}
struct ArcNode//表结点
{
int adjvex;//该弧所指向的顶点的位置
ArcNode *nextarc;//指向下一条弧的指针
InfoType info;//该弧相关信息的指针
};
struct VNode//头结点
{
VertexType data;//顶点信息
ArcNode *firstarc;//指向第一条依附在该顶点的弧的指针
};
VNode vertices[MAX_VERTEX_NUM];//头列表
int vexnum; //图的当前顶点数
int arcnum;//图的弧数
GraphKind kind;//图的种类
};
main.cpp
#include<iostream>
#include"CreateGraph.h"
using namespace std;
int main()
{
cout << "请输入一个整数,选择构建图的类型:" << endl;
cout << "1、构造无向图" << endl;
cout << "2、构造带权无向图" << endl;
cout << "3、构造有向图" << endl;
cout << "4、构造带权有向图" << endl;
int ch;
cin >> ch;
switch (ch)//如果要在case里面定义变量,需要用括号括起来{}
{
case 1:
{
cout << "构造无向图:" << endl;
ALGraph<char, int> udgGraph(8, UDG);
udgGraph.Create();
udgGraph.displayGraph();
break;
}
case 2:
{
cout << "构造带权无向图:" << endl;
ALGraph<char, int> wudgGraph(9, WUDG);
wudgGraph.Create();
wudgGraph.displayGraph();
break;
}
case 3:
{
cout << "构造有向图:" << endl;
ALGraph<char, int> dgGraph(6, DG);
dgGraph.Create();
dgGraph.displayGraph();
break;
}
case 4:
{
cout << "构造带权有向图:" << endl;
ALGraph<char, int> wdgGraph(6, WDG);
wdgGraph.Create();
wdgGraph.displayGraph();
break;
}
}
system("pause");
return 0;
}
结果为: