图的存储定义:
图的存储必须完整的,准确地反映顶点集和边集的信息。
图的存储的方式:
图的存储有2种基本方式:
- 邻接矩阵;
- 邻接表;
1.邻接矩阵:
邻接矩阵是用一个二维数组存储图中的边的信息。即用一个二维数组表示各个顶点之间的邻接关系。这个二维数组即称为邻接矩阵。
对于无权图而言,某两点之间若存在边即用1表示,否则用0表示。
- 对于无向图而言的邻接矩阵如下所示:
- 对于有向图而言的邻接矩阵如下所示:
注意:
无向图的邻接矩阵是对称的,而有向图的邻接矩阵不一定对称。
邻接矩阵的定义:
typedef struct MGraph{
char Vexnum[MAXVEX]; //顶点集
int ARC[MAXVEX][MAXVEX];//邻接矩阵
int vexnum;//顶点数
int edgenum;//边数
};
邻接矩阵的创建:
void Creat(MGraph& G)
{
int i;//行
int j;//列
int w;//权
cout << "请输入顶点数: " << endl;
cin >> G.vexnum;
cout << "请输入边数: " << endl;
cin >> G.edgenum;
cout << "请输入顶点信息: " << endl;
for (i = 0; i < G.vexnum; i++)
{
cin >> G.Vexnum[i];
}
for (i = 0; i < G.vexnum; i++)
{
for (j = 0; j < G.vexnum; j++)
{
G.ARC[i][j] = INF;
}
}
for (int k = 0; k < G.edgenum; k++)
{
cout << "请输入边(vi,vj)的下标i , j和权w: " << endl;
cin >> i >> j >> w;
G.ARC[i][j] = w;
//G.ARC[j][i] = G.ARC[i][j]; //无向图需要这句
}
}
完整代码:
#include<iostream>
#include<iomanip>
using namespace std;
#define INF 9999
#define MAXVEX 10
typedef struct MGraph{
char Vexnum[MAXVEX]; //顶点集
int ARC[MAXVEX][MAXVEX];//邻接矩阵
int vexnum;//顶点数
int edgenum;//边数
};
//创建图的邻接矩阵
void Creat(MGraph& G)
{
int i;//行
int j;//列
int w;//权
cout << "请输入顶点数: " << endl;
cin >> G.vexnum;
cout << "请输入边数: " << endl;
cin >> G.edgenum;
cout << "请输入顶点信息: " << endl;
for (i = 0; i < G.vexnum; i++)
{
cin >> G.Vexnum[i];
}
for (i = 0; i < G.vexnum; i++)
{
for (j = 0; j < G.vexnum; j++)
{
G.ARC[i][j] = INF;
}
}
for (int k = 0; k < G.edgenum; k++)
{
cout << "请输入边(vi,vj)的下标i , j和权w: " << endl;
cin >> i >> j >> w;
G.ARC[i][j] = w;
//G.ARC[j][i] = G.ARC[i][j]; //无向图需要这句
}
}
void Print(MGraph G) {
cout << "图的邻接矩阵信息如下: " << endl;
for (int i = 0; i < G.vexnum; i++)
{
for (int j = 0; j < G.vexnum; j++)
{
cout << G.ARC[i][j]<<setw(5);
}
cout << endl;
}
}
int main() {
MGraph G;
Creat(G);
Print(G);
return 0;
}
执行结果:
2.邻接表:
由邻接矩阵可以发现,其实邻接矩阵对于稀疏矩阵而言,也就是使用邻接矩阵会浪费大量的空间(大量的不存在的边占用空间)。为了解决这个问题,于是有了邻接表。
领接表相当于是由两部分组成的,一部分是对图中顶点存储的顺序表,称之为顶点表。边表包含了顶点的值(data)和边表头指针(firstarc),另一部分是对顶点所临接的顶点域(adjvex)和下一结点的指针域(next),称之为边表,边表采用单链表存储。
邻接表的定义:
typedef struct EdgeNode {
int adjvex; //这条边的另一个顶点
int weight; //权
EdgeNode* next; //指向下一条边
};
typedef struct VexNode {
char data;
EdgeNode* first;
};
typedef struct GraAdjList {
VexNode AdjList[MAXVEX];
int vexnum;
int edgenum;
};
邻接表的创建:
void initGraph(GraAdjList &G)
{
int i, j, k, w;
EdgeNode* e = NULL;
EdgeNode* q = NULL;
cout << "输入顶点数和边数: " << endl;
cin >> G.vexnum >> G.edgenum;
cout << "输入顶点信息: " << endl;
for (k = 0; k < G.vexnum; k++)
{
cin >> G.AdjList[k].data;
G.AdjList[k].first = NULL;
}
//建立边表
for (k = 0; k < G.edgenum; k++)
{
cout << "请输入边(vi,vj)的下标:i,j和权w: " << endl;
cin >> i >> j >> w;
e = new EdgeNode;
e->adjvex = j;
e->weight = w;
//头插法
e->next = G.AdjList[i].first;
G.AdjList[i].first = e;
//无向图还需要加
q = new EdgeNode;
q->adjvex = i;
q->weight = w;
q->next = G.AdjList[j].first;
G.AdjList[j].first = q;
}
}
完整代码:
#include<iostream>
#define MAXVEX 1000
using namespace std;
//边表
typedef struct EdgeNode {
int adjvex; //这条边的另一个顶点
int weight; //权
EdgeNode* next; //指向下一条边
};
typedef struct VexNode {
char data;
EdgeNode* first;
};
typedef struct GraAdjList {
VexNode AdjList[MAXVEX];
int vexnum;
int edgenum;
};
void initGraph(GraAdjList &G)
{
int i, j, k, w;
EdgeNode* e = NULL;
EdgeNode* q = NULL;
cout << "输入顶点数和边数: " << endl;
cin >> G.vexnum >> G.edgenum;
cout << "输入顶点信息: " << endl;
for (k = 0; k < G.vexnum; k++)
{
cin >> G.AdjList[k].data;
G.AdjList[k].first = NULL;
}
//建立边表
for (k = 0; k < G.edgenum; k++)
{
cout << "请输入边(vi,vj)的下标:i,j和权w: " << endl;
cin >> i >> j >> w;
e = new EdgeNode;
e->adjvex = j;
e->weight = w;
//头插法
e->next = G.AdjList[i].first;
G.AdjList[i].first = e;
//无向图还需要加
q = new EdgeNode;
q->adjvex = i;
q->weight = w;
q->next = G.AdjList[j].first;
G.AdjList[j].first = q;
}
}
void print(GraAdjList G)
{
cout << "打印邻接表: " << endl;
EdgeNode* p;
for (int i = 0; i < G.vexnum; i++)
{
cout << "顶点: " << G.AdjList[i].data << "--";
for (p = G.AdjList[i].first; p; p = p->next)
{
cout << p->adjvex << "(" << p->weight << ")" << " ";
}
cout << endl;
}
}
int main() {
GraAdjList G;
initGraph(G);
print(G);
return 0;
}
执行结果: