无向图的邻接矩阵
通过用邻接矩阵来表示无向图。如下无向图G1的邻接矩阵:
![无向图G1的邻接矩阵](https://img-blog.csdnimg.cn/img_convert/7794cf2c98e1b2090e40fa587858f156.png)
无向图G1包含了“A, B, C, D, E, F, G”共七个顶点,而且包含了“(A, C), (A, D), (A, F), (B, C), (C, D), (E, G), (F, G)”共七条边。由于这是无向图,所以(A, C)和(C, A)是同一条边,这里列举边时,按照字母先后顺序列举的。
无向图G1右边的邻接矩阵在内存中的邻接矩阵示意图。A[i][j] = 1
表示第i个顶点与第j个顶点是邻接点,A[i][j] = 0
表示它们不是邻接点。而i, j表示第i行和第j列的值。如:A[1, 2] = 1 表示第1个顶点B和第二个顶点C是邻接点。
代码实现
#include <iostream>
using namespace std;
#define MAX 100
class MatrixUDG
{
private:
char mVexs[MAX]; //顶点集合
int mVexNum; //顶点数
int mEdgNum; //边数
int mMatrix[MAX][MAX]; //邻接矩阵
public:
//创建图(手动输入)
MatrixUDG();
//创建图(用提供的顶点和边)
MatrixUDG(char *vexs, int vNum, char (*edges)[2], int eNum);
~MatrixUDG();
//打印邻接表
void print();
//输入一个合法字母
char readChar();
//获得一个字母在顶点数组的下标
int getPosition(char ch);
};
MatrixUDG::MatrixUDG()
{
char c1, c2;
int p1, p2;
cout << "输入顶点数:";
cin >> mVexNum;
cout << "输入边数:";
cin >> mEdgNum;
if (mVexNum < 1 || mEdgNum < 1 || (mEdgNum > (mVexNum * (mVexNum - 1))))
{
cout << "输入有误!" << endl;
return;
}
for (int i = 0; i < mVexNum; ++i)
{
cout << "vertex(" << i << "):";
mVexs[i] = readChar();
}
for (int j = 0; j < mEdgNum; ++j)
{
cout << "edge(" << j << "):";
c1 = readChar();
c2 = readChar();
p1 = getPosition(c1);
p2 = getPosition(c2);
if (p1 == -1 || p2 == -1)
{
cout << "输入的边错误!" << endl;
return;
}
mMatrix[p1][p2] = 1;
mMatrix[p2][p1] = 1;
}
}
MatrixUDG::MatrixUDG(char *vexs, int vNum, char (*edges)[2], int eNum)
{
if (vNum > MAX)
return;
mVexNum = vNum;
mEdgNum = eNum;
//初始化顶点
for (int i = 0; i < mVexNum; ++i)
mVexs[i] = vexs[i];
int p1, p2;
for (int j = 0; j < mEdgNum; ++j)
{
//获得边的起始点和结束点
p1 = getPosition(edges[j][0]);
p2 = getPosition(edges[j][1]);
//将连线的两个点都置为1
if (p1 == -1 || p2 == -1)
{
cout << "输入的边错误!" << endl;
return;
}
mMatrix[p1][p2] = 1;
mMatrix[p2][p1] = 1;
}
}
MatrixUDG::~MatrixUDG()
{
}
int MatrixUDG::getPosition(char ch)
{
for (int 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()
{
for (int i = 0; i < mVexNum; ++i)
{
for (int 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 vNum = sizeof(vexs) / sizeof(vexs[0]);
int eNum = sizeof(edges) / sizeof(edges[0]);
//1. 根据提供的数据生成
// MatrixUDG mudg(vexs, vNum, edges, eNum);
// mudg.print();
//2. 手动生成
MatrixUDG mudg1;
mudg1.print();
}
手动输入时运行结果如下:
输入顶点数:7
输入边数:7
vertex(0):A
vertex(1):B
vertex(2):C
vertex(3):D
vertex(4):E
vertex(5):F
vertex(6):G
edge(0):AC
edge(1):AD
edge(2):AF
edge(3):BC
edge(4):CD
edge(5):EG
edge(6):FG
0 0 1 1 0 1 0
0 0 1 0 0 0 0
1 1 0 1 0 0 0
1 0 1 0 0 0 0
0 0 0 0 0 0 1
1 0 0 0 0 0 1
0 0 0 0 1 1 0
无向图的邻接表
通过用邻接表来表示无向图。如下无向图G1的邻接表:
![无向图G1的邻接表](https://img-blog.csdnimg.cn/img_convert/b32623989098d127762e25eac868acea.png)
无向图G1包含了“A, B, C, D, E, F, G”共七个顶点,而且包含了“(A, C), (A, D), (A, F), (B, C), (C, D), (E, G), (F, G)”共七条边。
无向图G1右边的邻接表示意图如上图。每个顶点都包含一个链表,该链表记录了“该顶点的邻接点的序号”。顶点C包含的链表所包含的数据分别是“0、1、3”,而“0、1、3”分别对应“A、B、D”的序号,“A、B、D”都是C的邻接点。就是通过这种方式记录图的信息的。
代码实现
#include <iostream>
using namespace std;
#define MAX 100
class ListUDG
{
private:
//每一条边
struct ENode
{
int iVex; //指向的顶点的位置
ENode *nextEdge = NULL; //指向顶点的下一条边的指针
};
//数组中存储的顶点
struct VNode
{
char data;
ENode *firstEdge = NULL; //指向第一条该顶点的边
};
private:
int mVexNum; //图的顶点数目
int mEdgeNum; //图的边的数目
VNode mVexs[MAX]; //存储顶点
public:
ListUDG();
ListUDG(char vexs[], int vNum, char edges[][2], int eNum);
~ListUDG();
//打印邻接表
void print();
private:
//读取一个合法的输入字符
char readChar();
//返回字符ch在的位置
int getPosition(char ch);
//将node结点链接到list的最后
void linkLast(ENode *list, ENode *node);
};
ListUDG::ListUDG()
{
char c1, c2;
int p1, p2;
ENode *node1, *node2;
cout << "输入顶点数:";
cin >> mVexNum;
cout << "输入边数:";
cin >> mEdgeNum;
if (mVexNum > MAX || mEdgeNum > MAX || mVexNum < 1 || mEdgeNum < 1 || (mEdgeNum > (mVexNum * (mVexNum - 1))))
{
cout << "输入有误!" << endl;
return;
}
for (int i = 0; i < mVexNum; ++i)
{
cout << "vertex(" << i << "):";
mVexs[i].data = readChar();
}
//初始化邻接表的边
for (int j = 0; j < mEdgeNum; ++j)
{
cout << "edge(" << j << "):";
c1 = readChar();
c2 = readChar();
p1 = getPosition(c1);
p2 = getPosition(c2);
if (p1 == -1 || p2 == -1)
{
cout << "输入的边有错误!" << endl;
return;
}
node1 = new ENode();
node1->iVex = p2;
if (mVexs[p1].firstEdge == NULL)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
node2 = new ENode();
node2->iVex = p1;
if (mVexs[p2].firstEdge == NULL)
mVexs[p2].firstEdge = node2;
else
linkLast(mVexs[p2].firstEdge, node2);
}
}
ListUDG::ListUDG(char *vexs, int vNum, char (*edges)[2], int eNum)
{
if (vNum > MAX || eNum > MAX)
return;
char c1, c2;
int p1, p2;
ENode *node1, *node2;
mVexNum = vNum;
mEdgeNum = eNum;
for (int i = 0; i < mVexNum; ++i)
{
mVexs[i].data = vexs[i];
}
for (int j = 0; j < mEdgeNum; ++j)
{
c1 = edges[j][0];
c2 = edges[j][1];
p1 = getPosition(c1);
p2 = getPosition(c2);
if (p1 == -1 || p2 == -1)
{
cout << "输入的边有错误!" << endl;
return;
}
node1 = new ENode();
node1->iVex = p2;
if (mVexs[p1].firstEdge == NULL)
mVexs[p1].firstEdge = node1;
else
linkLast(mVexs[p1].firstEdge, node1);
node2 = new ENode();
node2->iVex = p1;
if (mVexs[p2].firstEdge == NULL)
mVexs[p2].firstEdge = node2;
else
linkLast(mVexs[p2].firstEdge, node2);
}
}
ListUDG::~ListUDG() {}
void ListUDG::linkLast(ENode *list, ENode *node)
{
ENode *p = list;
while (p->nextEdge)
p = p->nextEdge;
p->nextEdge = node;
}
int ListUDG::getPosition(char ch)
{
for (int i = 0; i < mVexNum; ++i)
{
if (mVexs[i].data == ch)
return i;
}
return -1;
}
char ListUDG::readChar()
{
char ch;
do
{
cin >> ch;
} while (!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')));
return ch;
}
void ListUDG::print()
{
ENode *node;
for (int i = 0; i < mVexNum; ++i)
{
cout << i << "(" << mVexs[i].data << "):";
node = mVexs[i].firstEdge;
while (node != NULL)
{
cout << node->iVex << "(" << mVexs[node->iVex].data << ")";
node = node->nextEdge;
}
cout << endl;
}
}
int main(int argc, char **argv)
{
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 vNum = sizeof(vexs) / sizeof(vexs[0]);
int eNum = sizeof(edges) / sizeof(edges[0]);
//1. 根据提供的数据生成
// ListUDG ludg(vexs, vNum, edges, eNum);
// ludg.print();
//2. 手动输入
ListUDG ludg;
ludg.print();
return 0;
}
手动输入时运行结果如下:
输入顶点数:7
输入边数:7
vertex(0):A
vertex(1):B
vertex(2):C
vertex(3):D
vertex(4):E
vertex(5):F
vertex(6):G
edge(0):AC
edge(1):AD
edge(2):AF
edge(3):BC
edge(4):CD
edge(5):EG
edge(6):FG
0(A):2(C)3(D)5(F)
1(B):2(C)
2(C):0(A)1(B)3(D)
3(D):0(A)2(C)
4(E):6(G)
5(F):0(A)6(G)
6(G):4(E)5(F)