图的存储
图分为有向图和无向图,在此基础上还有有权和无权图。
有向图适用于邻接表存储,无向图适用于邻接矩阵。
无向图的存储结构——邻接矩阵
无向图的邻接矩阵是对称矩阵,可以压缩为n(n+1)/2;
有向图的邻接矩阵不一定是对称矩阵,存储空间为n²;
邻接矩阵的创建较为简单,只需对矩阵先进行初始化,再将输入的信息放进矩阵,修改矩阵的值即可
创建邻接矩阵
//构建邻接矩阵
#define WQ 65535
void CreatGraph(int n, int e) {
for (int i = 1; i <= n; i++) {//先对矩阵初始化
for (int j = 1; j <= n; j++) {
edge[i][j] = WQ;//WQ即无穷大,默认无穷大为不连通
if (i == j) edge[i][j] = edge[j][i] = 0;
}
}
for (int k = 0; k < e; k++) {//输入的边的起始点和终点及权值,进行修改
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[a][b] = c;
edge[b][a] = edge[a][b];
}
}
有向图的存储结构———邻接表
邻接表:两部分① 顺序存储的顶点表②边链表:对图的每一个顶点都建立一个单链表,包含顶点的所有邻接顶点
创建邻接表
//邻接表的结构
typedef struct Vertex {
int vername;//顶点名称
struct edge* adjacent;//边链表的头指针
}Vertex;
Vertex head[200];
typedef struct edge {
int veradj;//邻接顶点序号
int cost;//权值
struct edge* link;//指向下一个边结点的指针
}edge;
//从题目中复制下了一部分代码
```for (int i = 1; i <= n; i++)//初始化
{
head[i].vername = i;//head数组存放顶点序号
head[i].adjacent = NULL;//初始化为空
}
for (int i = 1; i <= m; i++)
{//输入各点信息
***//创建邻接表***
scanf("%d %d", &a, &b);//a指向b
edge* edge1 = creat(b);//某一论文指向的顶点b
edge* p = head[a].adjacent;//p为边链表头指针
if (p == NULL)
head[a].adjacent = edge1;//即a节点没有邻接顶点
else
{ //尾插
p = head[a].adjacent;
while (p->link)
{
p = p->link;
}
p->link = edge1; //放在最后
}
}
图的遍历
深度优先遍历(DFS)
递归算法
迭代算法
广度优先遍历(BFS)
类似于树的层次遍历,是分层搜索的过程,不需要回溯,不需要递归。
算法中利用队列记录还未被处理的节点,利用辅助数组vis[ ]给访问过的顶点加标记。
需要注意的是:DFS和BFS只是一种思想一种算法,并不是只局限于这一种情况,还有许多可以利用DFS 和 BFS 的情况,需要多加思考