邻接矩阵实现(有向邻接矩阵)、(无向邻接矩阵) 基于C++

邻接矩阵

邻接表的实现请看这里

图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。
设图G有n个顶点,则邻接矩阵是一个nn的方阵,定义为:

看一个实例,下图左就是一个无向图。

从上面可以看出,无向图的边数组是一个对称矩阵。所谓对称矩阵就是n阶矩阵的元满足aij = aji。即从矩阵的左上角到右下角的主对角线为轴,右上角的元和左下角相对应的元全都是相等的。
从这个矩阵中,很容易知道图中的信息。
(1)要判断任意两顶点是否有边无边就很容易了;
(2)要知道某个顶点的度,其实就是这个顶点vi在邻接矩阵中第i行或(第i列)的元素之和;
(3)求顶点vi的所有邻接点就是将矩阵中第i行元素扫描一遍,arc[i][j]为1就是邻接点;
而有向图讲究入度和出度,顶点vi的入度为1,正好是第i列各数之和。顶点vi的出度为2,即第i行的各数之和。

若图G是网图,有n个顶点,则邻接矩阵是一个nn的方阵,定义为:

邻接表和邻接矩阵的区别:

对于一个具有n个顶点e条边的无向图
它的邻接表表示有n个顶点表结点2e个边表结点
对于一个具有n个顶点e条边的有向图
它的邻接表表示有n个顶点表结点e个边表结点
如果图中边的数目远远小于n^2称作稀疏图,这是用邻接表表示比用邻接矩阵表示节省空间
如果图中边的数目接近于n^2,对于无向图接近于n*(n-1)称作稠密图,考虑到邻接表中要附加链域,采用邻接矩阵表示法为宜

邻接矩阵(有向邻接矩阵图)的代码实现(C++):

/*
	邻接矩阵图
	@author lph
	
*/

#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;

constexpr auto MAX = 100;
class MatrixDG {
	private:
        char mVexs[MAX];    // 顶点集合
        int mVexNum;             // 顶点数
        int mEdgNum;             // 边数
        int mMatrix[MAX][MAX];   // 邻接矩阵

    public:
        // 创建图(自己输入数据)
		MatrixDG();
        // 创建图(用已提供的矩阵)
        MatrixDG(char vexs[], int vlen, char edges[][2], int elen);
		~MatrixDG();

        // 打印矩阵队列图
        void print();

	private:
        // 读取一个输入字符
        char readChar();
        // 返回ch在mMatrix矩阵中的位置
        int getPosition(char ch);
};

/*
	创建图(自己输入数据)
*/
MatrixDG::MatrixDG() {
	char c1, c2;
	int i, p1, p2;

	// 输入顶点数和边数
	cout << "input vertex number: ";
	cin >> mVexNum;
	cout << "input edge number: ";
	cin >> mEdgNum;
	if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
		cout << "input error: invalid parameters!" << endl;
		return;
	}

	// 初始化顶点
	for (i = 0; i < mVexNum; ++i) {
		cout << "vertex(" << i << "):";
		mVexs[i] = readChar();
	}
	// 初始化边
	// 先把所有起始顶点到其他顶点的边初始化为0
	for (i = 0; i < mVexNum; i++)
	{
		for (int j = 0; j < mVexNum; ++j)
			mMatrix[i][j] = 0;
	}
	for (i = 0; i < mEdgNum; ++i) {
		// 读取边的起始顶点和结束顶点
		cout << "edge(" << i << "):";
		c1 = readChar();
		c2 = readChar();

		p1 = getPosition(c1);
		p2 = getPosition(c2);
		if (p1 == -1 || p2 == -1) {
			cout << "input error: invalid edge!" << endl;
			return;
		}
		mMatrix[p1][p2] = 1;
	}
}

/*
	创建图(用已经有的矩阵)
	参数说明:
	vexs  -- 顶点数组
	vlen  -- 顶点数组的长度
	edges -- 边数组
	elen  -- 边数组的长度
*/
MatrixDG::MatrixDG(char vexs[], int vlen, char edges[][2], int elen) {
	int i, p1, p2;
	// 初始化顶点数和边数
	mVexNum = vlen;
	mEdgNum = elen;
	// 初始化顶点
	for (i = 0; i < mVexNum; ++i) 
		mVexs[i] = vexs[i];
	// 初始化边
	// 先把所有起始顶点到其他顶点的边初始化为0
	for (i = 0; i < mVexNum; i++)
	{
		for (int j = 0; j < mVexNum; ++j)
			mMatrix[i][j] = 0;
	}
	for (i = 0; i < mEdgNum; ++i) {
		// 读取边的起始顶点和结束顶点
		p1 = getPosition(edges[i][0]);
		p2 = getPosition(edges[i][1]);
		mMatrix[p1][p2] = 1;
	}
}
/*
	析构函数
*/
MatrixDG::~MatrixDG() {

}
/*
	返回ch在mMatrix矩阵中的位置
*/
int MatrixDG::getPosition(char ch) {
	int i;
	for (i = 0; i < mVexNum; ++i) 
		if (mVexs[i] == ch)
			return i;
	return -1;
	
}
/*
	读取一个输入字符
*/
char MatrixDG::readChar() {
	char ch;
	do {
		cin >> ch;
	} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
	return ch;
}
/*
	打印矩阵队列图
*/
void MatrixDG::print() {
	int i, j;
	cout << "Matrix Graph:" << endl;
	for (i = 0; i < mVexNum; ++i) {
		for (j = 0; j < mVexNum; ++j)
			cout << mMatrix[i][j] << " ";
		cout << endl;
	}
}
int main() {
	char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'D', 'F', 'G' };
	char edges[][2] = {
		{'A', 'B'},
		{'B', 'C'},
		{'B', 'E'},
		{'B', 'F'},
		{'C', 'E'},
		{'D', 'C'},
		{'E', 'B'},
		{'E', 'D'},
		{'F', 'G'}
	};
	int vlen = sizeof(vexs) / sizeof(vexs[0]);
	int elen = sizeof(edges) / sizeof(edges[0]);
	MatrixDG* pG;

	// 自定义图(输入矩阵队列)
	//pG = new MatrixDG();
	// 采用已经有的数据
	pG = new MatrixDG(vexs, vlen, edges, elen);
	// 打印结果
	pG->print();
	return 0;
}

 打印结果(有向邻接矩阵图)

自己输入的数据打印结果(有向邻接矩阵图)

 邻接矩阵(无向邻接矩阵图)的代码实现(C++):

/**
 * C++: 邻接矩阵表示的"无向图(Adjacency Matrix in Undirected Graph)"
 *
 * @author lph
 * 
 */

#include <iomanip>
#include <iostream>
#include <vector>
using namespace std;

constexpr auto MAX = 100;
class MatrixUDG {
private:
	char mVexs[MAX];		// 顶点集合
	int mVexNum;			// 顶点数
	int mEdgNum;			// 边数
	int mMatrix[MAX][MAX];  // 邻接矩阵
public:
	// 创建图(自己输入数据)
	MatrixUDG();
	// 创建图(用已经提供的数据)
	MatrixUDG(char vexs[], int vlen, char edges[][2], int elen);
	// 析构函数
	~MatrixUDG();
	// 打印矩阵
	void print();
private:
	// 读取一个输入字符
	char readChar();
	// 返回ch在mMatrix矩阵中位置
	int getPosition(char ch);
};

/*
	创建图(自己输入数据)
*/
MatrixUDG::MatrixUDG() {
	char c1, c2;
	int i,j, p1, p2;
	// 输入顶点数和边数
	cout << " input vertex number:";
	cin >> mVexNum;
	cout << " input edge number: ";
	cin >> mEdgNum;
	if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1)))) {
		cout << "input error: invalid parameters!" << endl;
		return;
	}

	// 初始化顶点
	for (i = 0; i < mVexNum; ++i) {
		cout << "vertex(" << i << "):";
		mVexs[i] = readChar();
	}
	// 初始化边
	// 先把所有起始顶点到其他顶点的边初始化为0
	for (i = 0; i < mVexNum; i++)
		for (j = 0; j < mVexNum; ++j)
			mMatrix[i][j] = 0;
	
	for (i = 0; i < mEdgNum; ++i) {
		// 读取边的起始顶点和结束顶点
		cout << "edge(" << i << "):";
		c1 = readChar();
		c2 = readChar();

		p1 = getPosition(c1);
		p2 = getPosition(c2);
		if (p1 == -1 || p2 == -1) {
			cout << "input error: invalid edge!" << endl;
			return;
		}
		mMatrix[p1][p2] = 1;
		mMatrix[p2][p1] = 1; //无向图
	}
}
/*
	创建图(用已经提供的数据)
	  vexs  -- 顶点数组
      vlen  -- 顶点数组的长度
      edges -- 边数组
      elen  -- 边数组的长度
*/
MatrixUDG::MatrixUDG(char vexs[], int vlen, char edges[][2], int elen) {
	int i, j, p1, p2;
	// 初始化顶点数和边数
	mVexNum = vlen;
	mEdgNum = elen;
	// 初始化顶点
	for (i = 0; i < mVexNum; ++i)
		mVexs[i] = vexs[i];
	// 初始化边
	// 先把所有起始顶点到其他顶点的边初始化为0
	for (i = 0; i < mVexNum; i++)
		for (int j = 0; j < mVexNum; ++j)
			mMatrix[i][j] = 0;
	for (i = 0; i < mEdgNum; ++i) {
		p1 = getPosition(edges[i][0]);
		p2 = getPosition(edges[i][1]);

		mMatrix[p1][p2] = 1;
		mMatrix[p2][p1] = 1;
	}
}
/*
 * 析构函数
 */
MatrixUDG::~MatrixUDG(){

}
/*
 * 返回ch在mMatrix矩阵中的位置
 */
int MatrixUDG::getPosition(char ch) {
	int i;
	for (i = 0; i < mVexNum; ++i)
		if (mVexs[i] == ch)
			return i;
	return -1;
}
/*
	读取一个输入字符
*/
char MatrixUDG::readChar() {
	char ch;
	do {
		cin >> ch;
	} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
	return ch;
}
/*
 * 打印矩阵队列图
 */
void MatrixUDG::print(){
	int i, j;
	cout << "Martix Graph:" << endl;
	for (i = 0; i < mVexNum; i++){
		for (j = 0; j < mVexNum; j++)
			cout << mMatrix[i][j] << " ";
		cout << endl;
	}
}
int main(){
	char vexs[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
	char edges[][2] = {
		{'A', 'C'},
		{'A', 'D'},
		{'A', 'F'},
		{'B', 'C'},
		{'C', 'D'},
		{'E', 'G'},
		{'F', 'G'} };
	int vlen = sizeof(vexs) / sizeof(vexs[0]);
	int elen = sizeof(edges) / sizeof(edges[0]);
	MatrixUDG* pG;

	// 自定义"图"(输入矩阵队列)
	//pG = new MatrixUDG();
	// 采用已有的"图"
	pG = new MatrixUDG(vexs, vlen, edges, elen);

	pG->print();   // 打印图

	return 0;
}

 打印结果(无向邻接矩阵图)

自己输入的数据打印结果(无向邻接矩阵图)

 

邻接表的实现请看这里

  • 11
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值