本文已参与「新人创作礼」活动,一起开启掘金创作之路。
邻接矩阵
直接用一个二维数组存储
采用程序化的步骤:
- 建立包含全部顶点但没有边的图
- 逐条插入边, 从而建立一个图
#include <iostream>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <cstring>
using namespace std;
const int MaxV = 100;
/*图结点的定义*/
typedef struct GNode{
int Nv; //顶点数
int Ne; //边数
int F[MaxV][MaxV]; //邻接矩阵
char Data[MaxV]; //顶点数据, 若顶点无数据, data[]可以不出现
} * MGraph;
/*边的定义*/
typedef struct ENode{
int v1, v2; //有向边<v1, v2>
int Weight; //边权重
} * Edge;
MGraph CreateGraph(int Nv)
{ /*初始化一个有Nv个顶点但没有边的图*/
MGraph G = (MGraph)malloc(sizeof(GNode));
//MGraph G = new GNode{0};
G->Nv = Nv; G->Ne = 0;
for (int i = 0; i < Nv; i++)
for (int j = 0; j < Nv; j++)
G->F[i][j] = INT_MAX;
return G;
}
void InsertEdge(MGraph G, Edge E)
{ /*插入边<v1, v2>*/
G->F[E->v1][E->v2] = E->Weight;
//G->F[E->v2][E->v2] = E->Weight; //如果是有向图, 还要插入边<v2, v1>
}
MGraph BuildGraph()
{ /*建立一个完整的图*/
MGraph G;
Edge E = (Edge)malloc(sizeof(ENode));
//Edge E = new ENode;
int Nv;
cin >> Nv;
G = CreateGraph(Nv); //初始化一个图
cin >> G->Ne; //指针有地址存储图后, 可直接对图进行访问
for (int i = 0; i < G->Ne; i++)
{
cin >> E->v1 >> E->v2 >> E->Weight;
InsertEdge(G, E);
}
free(E);
//delete E;
// for (int i = 0; i < G->Nv; i++) //如果顶点有数据, 读入数据
// cin >> G->Data[i]; //下标是顶点的数字编号, char型是名称显示
return G;
}
int main()
{
//cout << "输入顶点数和边数, 然后输入边<v1, v2>, Weight" << endl;
MGraph G = BuildGraph();
for (int i = 0; i < G->Nv; i++) //输出邻接矩阵
{
for (int j = 0; j < G->Nv; j++)
cout << G->F[i][j] << " ";
cout << endl;
}
free(G);
//delete G;
system("pause");
return 0;
}
示例图:
输入
5 8
0 2 6
0 3 3
1 0 9
1 2 4
2 4 7
3 1 5
3 4 8
4 3 6
运行结果
邻接表
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int MaxV = 100;
/*边的定义*/
typedef struct ENode{
int v1, v2; //有向边<v1, v2>
int Weight; //边权重
} * Edge;
/*邻接点的定义*/
struct AdjVNode{
int AdjV; //邻接点下标v
int Weight; //边权重, 顶点表头结点u, 则边<u, v>
AdjVNode *Next; //指向下一邻接点的指针
};
/*顶点表头结点的定义*/
typedef struct VNode{
AdjVNode *FirstEdge; //边表头指针
int Data; //存顶点数据, 多数情况顶点无数据, 此时Data可以不用出现
} AdjList[MaxV];
/*图结点的定义*/
typedef struct GNode{
int Nv, Ne; //顶点和边数
AdjList L;
} * LGraph;
LGraph CreateGraph(int Nv)
{ /*初始化一个有Nv个顶点但没有边的图*/
LGraph G = (LGraph)calloc(1, sizeof(GNode)); //申请存储空间并初始化
//LGraph G = new GNode{0};
G->Nv = Nv;
return G;
}
void InsertEdge(LGraph G, Edge E)
{ /*边的插入, 每次的插在邻接顶点表头*/
AdjVNode *newVNode;
/*插入边<v1, v2>*/
newVNode = (AdjVNode *)malloc(sizeof(AdjVNode));
newVNode->AdjV = E->v2; newVNode->Weight = E->Weight; //将边E的数据赋给newVNode
newVNode->Next = G->L[E->v1].FirstEdge; //两部操作把v2插入v1表头, 构成有向边<v1, v2>
G->L[E->v1].FirstEdge = newVNode;
/*若是无向图, 再插入边<v2, v1>*/
// newVNode = (AdjVNode *)malloc(sizeof(AdjVNode));
// newVNode->AdjV = E->v1; newVNode->Weight = E->Weight; //将边E的数据赋给newVNode
// newVNode->Next = G->L[E->v2].FirstEdge; //两部操作把v2插入v1表头, 构成有向边<v1, v2>
// G->L[E->v2].FirstEdge = newVNode;
}
LGraph BuildGraph()
{
int Nv;
LGraph G;
Edge E = (Edge)malloc(sizeof(ENode));
//Edge E = new ENode;
cin >> Nv; G = CreateGraph(Nv); //初始化
cin >> G->Ne;
for (int i = 0; i < G->Ne; i++)
{
cin >> E->v1 >> E->v2 >> E->Weight;
InsertEdge(G, E);
}
free(E); //不用了, 记得free
//delete E;
/*如果需要Data*/
// for (int i = 0; i < G->Nv; i++)
// cin >> G->L[i].Data;
return G;
}
int main()
{
LGraph G = BuildGraph();
AdjVNode *V;
for (int i = 0; i < G->Nv; i++)
{
cout << i << "->";
while (G->L[i].FirstEdge)
{
AdjVNode *V = G->L[i].FirstEdge;
cout << "(" << V->AdjV << " W:" << V->Weight << ")->";
G->L[i].FirstEdge = V->Next;
free(V); //每次访问完后删除
}
cout << "NULL" << endl;
}
free(G);
//delete G;
system("pause");
return 0;
}
运行结果