持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
邻接矩阵:
逻辑结构分为两部分:V和E集合,其中,V是顶点,E是边。
因此,用一个一维数组存放图中所有顶点数据;
用一个二维数组存放顶点间关系(边或弧)的数据,这个二维数组称为邻接矩阵。
邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵
我把它封装在一个类(Graph)里,来看看具体实现:
private:
int directionflag = 0;//方向标志
int netflag = 0;//是否为网标志
char node[MAXSIZE] = { 0 };//存放顶点(定义字符类型)
int arr[MAXSIZE][MAXSIZE] = { 0 };//邻接矩阵
int nodenum = 0, arcnum = 0;//图的点数和边数
protected:
//位置标记函数
void LocateVex(char v, int& i)
public:
//创建图函数
void CreatGraph()
//展示矩阵函数
void display()
//计算度函数
void calculatedu(char v)
//看是否有边或弧函数
void checkarm(char x, char y)
PS: 由于代码内含很多的解释,读者直接阅读代码即可~
代码如下:
#include<iostream>
using namespace std;
#define MAXSIZE 100//定义节点数
//定义图类
class Graph {
private:
int directionflag = 0;//方向标志
int netflag = 0;//是否为网标志
char node[MAXSIZE] = { 0 };//存放顶点(定义字符类型)
int arr[MAXSIZE][MAXSIZE] = { 0 };//邻接矩阵
int nodenum = 0, arcnum = 0;//图的点数和边数
protected:
//位置标记
void LocateVex(char v, int& i) {
i = 0;
for (; i < nodenum; i++) {
if (node[i] == v)
break;
}
}
public:
//建造图
void CreatGraph() {
//指引式创建图
cout << "请您配合输入图的信息:" << endl;
cout << "请输入0或1,“0”代表无向图,“1”代表有向图:";
cin >> directionflag;
cout << "请输入0或1,“0”代表非网图,“1”代表网图:";
cin >> netflag;
cout << "请分别输入顶点数和边数:";
cin >> nodenum >> arcnum;
//正式初始化
//输入顶点信息
cout << "请输入顶点的信息:" << endl;
for (int i = 0; i < nodenum; i++)
cin >> node[i];
//先给邻接矩阵的每个值都赋值0
for (int i = 0; i < nodenum; i++) {
for (int j = 0; j < nodenum; j++) {
arr[i][j] = 0;
}
}
//给图赋值
char v1, v2;
int w;//权值
int i, j;//位置标记
if (netflag == 1) {
//网图无向图
if (directionflag == 0) {
for (int k = 0; k < arcnum; k++) {
cout << "请输入一条边以及它的权值:";
cin >> v1 >> v2 >> w;
LocateVex(v1, i);
LocateVex(v2, j);
arr[i][j] = w;
arr[j][i] = w;
}
}
//网图有向图
else {
for (int k = 0; k < arcnum; k++) {
cout << "请输入一条边如ab按(a->b)的顺序以及它的权值:";
cin >> v1 >> v2 >> w;
LocateVex(v1, i);
LocateVex(v2, j);
arr[i][j] = w;
}
}
}
else {
//非网图无向图
if (directionflag == 0) {
for (int k = 0; k < arcnum; k++) {
cout << "请输入一条边的信息:";
cin >> v1 >> v2;
LocateVex(v1, i);
LocateVex(v2, j);
arr[i][j] = 1;
arr[j][i] = 1;
}
}
//非网图有向图
else {
for (int k = 0; k < arcnum; k++) {
cout << "请输入一条边按(a->b)的顺序";
cin >> v1 >> v2;
LocateVex(v1, i);
LocateVex(v2, j);
arr[i][j] = 1;
}
}
}
}
//展示矩阵
void display() {
for (int i = 0; i < nodenum; i++) {
for (int j = 0; j < nodenum; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
//计算度
void calculatedu(char v) {
int cnt = 0, x;
int incnt = 0, outcnt = 0;//incnt为入度outcnt为出度
LocateVex(v, x);
if (directionflag == 0) {//无向图
for (int i = 0; i < nodenum; i++) {
if (arr[x][i] != 0) {
cnt++;
}
}
cout << "无向图顶点" << v << "的度数为:" << cnt << endl;
}
else {//有向图
//求入度
for (int i = 0; i < nodenum; i++) {
if (arr[i][x] != 0) {
incnt++;
}
}
//求出度
for (int i = 0; i < nodenum; i++) {
if (arr[x][i] != 0) {
outcnt++;
}
}
cnt = incnt + outcnt;
cout << "有向图顶点" << v << "的入度为:" << incnt << endl << v << "的出度为:" << outcnt << endl << "总度数为:" << cnt << endl;
}
}
//看是否有边或弧
void checkarm(char x, char y) {
int i, j;
LocateVex(x, i);//找位置
LocateVex(y, j);
int z = 0;
if (arr[i][j] != 0 || arr[j][i] != 0) {
z = arr[i][j] > arr[j][i] ? arr[i][j] : arr[j][i];
}
if (z == 0) {
cout << x << y << "两点无边(弧)" << endl;
}
else if (z > 0 && netflag == 1) {
cout << x << y << "两点有边(弧)" << "它们的权值是" << z << endl;
}
else if (z > 0 && netflag == 0) {
cout << x << y << "两点有边(弧)" << endl;
}
}
};
int main()
{
Graph g;
//创建图
g.CreatGraph();
//展示矩阵
g.display();
//计算度数
g.calculatedu('A');
//看两点是否有边
g.checkarm('A', 'B');
system("pause");
cout << endl;
return 0;
}