图-无向图中从点u到点v的所有路径

输出无向图中从点u到点v的所有路径。这个问题可以通过深度优先搜索(DFS)来解决。

第一步:初始化路径和访问标记

  1. 设定变量:定义路径数组 path 来存储当前路径,d 为路径的当前长度,visit 数组用来标记节点是否已被访问。
  2. 初始化路径:将起点 u 添加到路径中,并标记为已访问。
void findpath(AGraph* G, int u, int v, int path[], int d, int visit[]) {
    int w, i;
    path[++d] = u; // 将当前节点u添加到路径中
    visit[u] = 1; // 标记节点u为已访问

第二步:检查是否到达目标节点

  1. 检查目标:如果当前节点 u 等于目标节点 v,则输出当前路径。
  2. 输出路径:遍历路径数组,打印出路径中的所有节点。
    if (u == v) {
        printf("\n");
        for (i = 0; i <= d; ++i)
            printf("%d ", path[i]);
    }

第三步:递归搜索所有可能的路径

  1. 遍历邻接点:通过邻接表遍历所有与当前节点 u 相邻的节点。
  2. 递归调用:对每个未访问的邻接点 w,递归调用 findpath 函数继续搜索。
    ArcNode* p = G->adjlist[u].firstarc;
    while (p != NULL) {
        w = p->adjvex;
        if (visit[w] == 0)
            findpath(G, w, v, path, d, visit);
        p = p->nextarc;
    }

第四步:回溯

  1. 取消访问标记:在回溯之前,将当前节点 u 的访问标记重置为未访问,以便其他路径可以重新访问此节点。
    visit[u] = 0;
}

完整的代码

void findpath(AGraph* G, int u, int v, int path[], int d, int visit[]) {
    int w, i;
    path[++d] = u; // 将当前节点u添加到路径中
    visit[u] = 1; // 标记节点u为已访问

    if (u == v) {
        printf("\n");
        for (i = 0; i <= d; ++i)
            printf("%d ", path[i]);
    }

    ArcNode* p = G->adjlist[u].firstarc;
    while (p != NULL) {
        w = p->adjvex;
        if (visit[w] == 0)
            findpath(G, w, v, path, d, visit);
        p = p->nextarc;
    }

    visit[u] = 0; // 取消访问标记,进行回溯
}

让我们通过一个简单的例子来展示变量在每一步的变化。假设我们有一个无向图,包含四个节点:A, B, C, D,并且有以下边:A-B, A-C, B-D, C-D。我们想要找出从节点A到节点D的所有路径。

图的表示

A -- B -- D
|    |
C -- D

变量初始化

  • path[]:用来存储路径的数组。
  • d:路径的当前长度。
  • visit[]:访问标记数组,用来记录节点是否被访问过。

深度优先搜索过程

步骤 1: 从节点A开始
  • d = 0, path[0] = A, visit[A] = 1
步骤 2: 访问A的邻接点B和C
  • d = 1, path[1] = B, visit[B] = 1

  • d = 2, path[2] = D, visit[D] = 1

    • 此时到达D,输出路径:A -> B -> D
  • 回溯到B,visit[D] = 0

  • d = 1, path[1] = C, visit[C] = 1

    • 访问C的邻接点D
  • d = 2, path[2] = D, visit[D] = 1

    • 再次到达D,输出路径:A -> C -> D
  • 回溯到C,visit[D] = 0

  • 回溯到A,visit[C] = 0, visit[B] = 0

完整的路径输出

A -> B -> D
A -> C -> D

表格:变量变化过程

步骤dpathvisit当前节点说明
初始化0[A][1]A从A开始,标记A为已访问
访问B1[A, B][1, 1]B访问A的邻接点B
访问D2[A, B, D][1, 1, 1]D从B访问D,输出路径A->B->D
回溯1[A, B][1, 0, 1]B回溯到B,取消D的访问标记
访问C2[A, C][1, 0, 1]C访问A的另一个邻接点C
访问D3[A, C, D][1, 0, 1, 1]D从C访问D,输出路径A->C->D
回溯2[A, C][1, 0, 0, 1]C回溯到C,取消D的访问标记
回溯1[A][1, 0, 0]A回溯到A,取消C的访问标记
回溯0[][0, 0, 0]-回溯到起点,取消A的访问标记
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值