1.图的存储结构
1.1邻接矩阵
邻接矩阵是图的顺序存储结构,由邻接矩阵的行数和列数可知图中的顶点数。对于无向图,邻接矩阵是对称的,矩阵中“1”的个数为图中总边数的2倍,矩阵中第i行或第i列的元素之和即为顶点i的度。对于有向图,矩阵中“1”的个数为图的边数,矩阵中第i行的元素之和即为顶点i的出度,第j列元素之和即为顶点j的入度。
邻接矩阵一般用二维数组表示。
1.2邻接表
邻接表是图的一种链式存储结构。所谓的邻接表就是对图中的每个顶点i建立一个单链表,每个单链表的第一个节点存放有关顶点的信息,把这一个节点看作链表的表头,其余节点存放有关边的信息。如下图所示:
邻接表的存储表示的定义如下:
typedef struct ArcNode//边结点
{
int adjvex; //该边所指向节点的 位置
double info; //边的信息存储权值
struct ArcNode *next; //下一条边的指针
}ArcNode;
typedef struct VNode //顶点结点
{
int data; //存储节点信息
ArcNode *firstarc; //边表头指针
}VNode;
typedef struct
{
VNode adjlist[Maxsize]; //邻接表
int n; //顶点数
int e; //边数
}AGraph;
当然也有简化的定义,比如不需要知道顶点信息,只需要知道边信息的简化邻接表如下:
typedef struct //简化的邻接表的边
{
int to; //该边指向的点
int val; //边的权值
int next; //下一条边序号,序号为el数组的下标
}edge;
int head[n]; //存储的是初始边的序号
edge el[e]; //边的数组
2.图的遍历
图的遍历算法主要有深度优先搜索遍历(DFS)和广度优先搜索遍历(BFS),具体的思想不再做阐述,这边我们给出邻接矩阵形式的图的遍历和邻接表的图的遍历。
- 邻接矩阵的图的遍历代码:
#include<iostream>
#include<queue>
using namespace std;
int visit[50];
int map[50][50];
void dfs(int k,int n) //深搜,参数n为图的顶点数
{
int i;
cout<<k<<" ";
visit[k]=1;//千万不要忘
for(i=0;i<n;i++)
{
if(map[k][i]==1&&visit[i]==0)
dfs(i,n);
}
}
void bfs(int n) //广搜
{
int temp,i;
queue<int> q;
visit[0]=1; //注意广搜的时候必须是先访问后入队
cout<<0<<" ";
q.push(0);
while(!q.empty())
{
temp=q.front();
q.pop();
for(i=0;i<n;i++)
{
if(map[temp][i]==1&&visit[i]==0)
{
visit[i]=1;
cout<<i<<" ";
q.push(i);
}
}
}
}
int main()
{
int n,i,j;
cin>>n;
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cin>>map[i][j];
}
}
for(i=0;i<n;i++)
{
visit[i]=0;
}
for(i=0;i<n;i++) //每个顶点都要访问到
{
if(visit[i]==0)
{
bfs(n);
//dfs(n);
}
}
cout<<endl;
return 0;
}
- 邻接表的图的遍历代码:
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
typedef struct //简化的邻接表的边
{
int to;
int next;
}edge;
int ednum;
int *head;
int *visit;
edge *el;
void adde(int