邻接矩阵
图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中的边或弧的信息。
设图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;
}
打印结果(无向邻接矩阵图):
自己输入的数据打印结果(无向邻接矩阵图):