数据结构·邻接矩阵的设计(实验)

363 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}