图的存储方式
图是多对多的关系,它的存储通常有两种办法。邻接矩阵和邻接表。一般而言,对于稀疏图使用邻接表来存储,对于稠密图使用邻接矩阵来存储。下面给出邻接矩阵实现图的代码。
#include <iostream>
#include <cstdlib>
using namespace std;
#define MAX 100
typedef struct
{
char V[MAX]; //顶点集
int Matrix[MAX][MAX]; //邻接矩阵
int numV; //顶点个数
int numE; //边的个数
}Graph;
void CreateGraph(Graph *G)
{
int i, j, k;
cout << "请输入顶点数和边数:\n";
cin >> G->numV >> G->numE;
//getchar();
cout << "请输入顶点信息:\n";
for (i = 0; i < G->numV; i++)
cin >> G->V[i];
for (i = 0; i < G->numV; i++)
for (j = 0; j < G->numV; j++)
G->Matrix[i][j] = 0;
cout << "请输入边信息:(两个顶点)\n";
for (k = 0; k < G->numE; k++)
{
cin >> i >> j; //i和j之间有边
//因为无向图的矩阵是对称的
G->Matrix[i][j] = 1;
G->Matrix[j][i] = 1;
//如果是加权图,那么也应该输入权值。
}
}
int main()
{
int i, j;
Graph *graphHead = (Graph *)malloc(sizeof(Graph));
CreateGraph(graphHead);
cout << "邻接表如下所示:\n";
for (i = 0; i < graphHead->numV; i++)
{
for (j = 0; j < graphHead->numV; j++)
cout << graphHead->Matrix[i][j] << "\t";
cout << '\n';
}
system("pause");
}
测试一个正方形的输入,结果如下图所示。
邻接表的实现方式和散列表(哈希表)比较像,只是不需要散列函数而已。把所有的顶点放在了一个数组中。这样做适合稀疏图。代码实现如下:
#include<cassert>
#include<iostream>
#include<cstdlib>
using namespace std;
typedef struct AdjListNode_
{
int num; //顶点编号
int weight; //顶点权值
struct AdjListNode_ *next; //指向下一个节点
}AdjListNode;
typedef struct AdjList_
{
AdjListNode * head; //头指针
}AdjList;
typedef struct Graph_
{
int numv, nume; //顶点个数和边个数
AdjList *array;
}Graph;
/*创建V个顶点的图*/
Graph* CreateGraph(Graph *graph)
{
int m, n, w;
cout << "请输入图的顶点数:";
cin >> graph->numv;
cout << "请输入图的边数:";
cin >> graph->nume;
graph->array = new AdjList[graph->numv];
for (int i = 0; i < graph->numv; ++i)
{
graph->array[i].head = NULL; //初始化头结点
}
for (int i = 0; i < graph->nume; i++)
{
cout << "请输入边(起始点到终止点):";
cin >> m >> n;
cout << "请输入权值:";
cin >> w;
AdjListNode *newNode = new AdjListNode;
assert(newNode); //判断是否分配到空间
newNode->num = n;
newNode->weight = w; //begin顶点到end顶点的边的权重
newNode->next = graph->array[m].head; //新边插入到链表前面
graph->array[m].head = newNode;
//无向图需要在<m,n>和<n,m>都建立链接,所以重复上一步
newNode = new AdjListNode;
assert(newNode);
newNode->num = m;
newNode->weight = w;
newNode->next = graph->array[n].head;
graph->array[n].head = newNode;
}
return graph;
}
int main()
{
Graph *graph = new Graph;
graph = CreateGraph(graph);
cout << "邻接表输出如下:\n";
for (int i = 0; i < graph->numv; i++)
{
if (NULL == graph->array[i].head)
{
cout << i << endl;
}
else
{
cout << i ;
AdjListNode * temp = graph->array[i].head;
for (int j = 0; temp != NULL; j++)
{
cout << "->" << temp->num;
temp = temp->next;
}
cout << "\n";
}
}
system("pause");
}
测试一个这样的正方形输入,四个顶点分别标记为0,1,2,3.
测试的结果如下图所示。