您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C语言数据结构与算法中怎样完成图的遍历
## 一、图的基本概念与存储结构
### 1.1 图的定义与基本术语
图(Graph)是由顶点集合(Vertex)和边集合(Edge)组成的数据结构,记作G=(V,E)。根据边是否有方向可分为:
- **有向图**:边有方向性,用<u,v>表示
- **无向图**:边无方向性,用(u,v)表示
常见术语包括:
- 度(Degree):与顶点关联的边数
- 路径:顶点序列v1,v2,...,vn
- 连通图:任意两顶点间都有路径
### 1.2 图的常见存储方式
#### 邻接矩阵
```c
#define MAX_VERTEX 100
typedef struct {
int vertex[MAX_VERTEX]; // 顶点数组
int edge[MAX_VERTEX][MAX_VERTEX]; // 邻接矩阵
int vertexNum, edgeNum; // 顶点和边数
} MGraph;
typedef struct ArcNode { // 边结点
int adjvex; // 邻接点下标
struct ArcNode *next; // 下一条边
} ArcNode;
typedef struct VNode { // 顶点结点
int data; // 顶点信息
ArcNode *first; // 第一条边
} VNode, AdjList[MAX_VERTEX];
typedef struct {
AdjList vertices;
int vertexNum, edgeNum;
} ALGraph;
深度优先搜索采用回溯算法思想,沿着图的深度遍历顶点: 1. 访问起始顶点v 2. 选择一个与v相邻且未被访问的顶点w 3. 递归访问w 4. 当没有未访问的相邻顶点时回溯
int visited[MAX_VERTEX] = {0};
void DFS(MGraph G, int v) {
printf("%d ", G.vertex[v]);
visited[v] = 1;
for(int i = 0; i < G.vertexNum; i++) {
if(G.edge[v][i] && !visited[i]) {
DFS(G, i);
}
}
}
void DFS(ALGraph G, int v) {
printf("%d ", G.vertices[v].data);
visited[v] = 1;
ArcNode *p = G.vertices[v].first;
while(p) {
if(!visited[p->adjvex]) {
DFS(G, p->adjvex);
}
p = p->next;
}
}
广度优先搜索采用分层搜索策略: 1. 访问起始顶点v 2. 依次访问v的所有未访问邻接点 3. 按访问顺序对每个邻接点重复步骤2
void BFS(MGraph G, int v) {
int queue[MAX_VERTEX], front = 0, rear = 0;
printf("%d ", G.vertex[v]);
visited[v] = 1;
queue[rear++] = v;
while(front != rear) {
int cur = queue[front++];
for(int i = 0; i < G.vertexNum; i++) {
if(G.edge[cur][i] && !visited[i]) {
printf("%d ", G.vertex[i]);
visited[i] = 1;
queue[rear++] = i;
}
}
}
}
void BFS(ALGraph G, int v) {
int queue[MAX_VERTEX], front = 0, rear = 0;
printf("%d ", G.vertices[v].data);
visited[v] = 1;
queue[rear++] = v;
while(front != rear) {
int cur = queue[front++];
ArcNode *p = G.vertices[cur].first;
while(p) {
if(!visited[p->adjvex]) {
printf("%d ", G.vertices[p->adjvex].data);
visited[p->adjvex] = 1;
queue[rear++] = p->adjvex;
}
p = p->next;
}
}
}
void Components(ALGraph G) {
for(int i = 0; i < G.vertexNum; i++) {
if(!visited[i]) {
DFS(G, i); // 或BFS
printf("\n"); // 输出一个连通分量
}
}
}
void ShortestPath(ALGraph G, int v) {
int dist[MAX_VERTEX] = {0};
int queue[MAX_VERTEX], front = 0, rear = 0;
for(int i = 0; i < G.vertexNum; i++) {
dist[i] = -1; // 初始化距离
}
dist[v] = 0;
queue[rear++] = v;
while(front != rear) {
int cur = queue[front++];
ArcNode *p = G.vertices[cur].first;
while(p) {
if(dist[p->adjvex] == -1) {
dist[p->adjvex] = dist[cur] + 1;
queue[rear++] = p->adjvex;
}
p = p->next;
}
}
}
特性 | DFS | BFS |
---|---|---|
数据结构 | 栈(递归/显式) | 队列 |
空间复杂度 | O(h) h为最大深度 | O(w) w为最大宽度 |
适用场景 | 拓扑排序、连通性分析 | 最短路径、社交网络 |
实际选择建议: 1. 需要寻找最短路径时优先选择BFS 2. 检测环路或进行拓扑排序时使用DFS 3. 稠密图建议使用邻接矩阵 4. 稀疏图建议使用邻接表
图的遍历是图算法的基础,DFS和BFS分别体现了深度优先和广度优先的不同策略。实际应用中应根据具体问题特点选择合适的遍历方法,并结合适当的存储结构以获得最佳性能。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。