设计并实现求两点间所有路径的算法

Project 1

实验题目

设计并实现求两点间所有路径的算法。

程序设计

DFS算法
  • 深度优先遍历:
    深度优先搜索(Depth_First Search)遍历类似于树的先根遍历,是树的先根遍历的推广。
    假设给定图G,图中所有顶点未曾被访问过,则深度优先搜索可以从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。这是一个递归的过程。
  • 深度优先遍历的过程
    假设给定图G,设x 是当前被访问顶点, 在对x 做过访问标记后, 选择一条从x出发的未检测过的边(x,y)。若发现顶点y 已访问过,则重新选择另一条从x 出发的未检测过的边,否则若顶点y未被访问过,沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y 出发的所有路径,即访问完所有从y 出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x 出发的未检测过的边。上述过程直至从x 出发的所有边都已检测过为止。此时,若x 不是源点,则回溯到在x 之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G 是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。
表存储结构:邻接表
运用DFS查找两点间所有路径的算法思想:
  • 查找:从起始的城市对应的顶点开始,逐次访问其邻接顶点。访问一个顶点时,标记为1,将其存入数组中。如果被访问的点在其此次所在的路径中之前已被访问(包括此次访问到的是起始顶点)或该顶点没有邻接顶点了且该顶点不是目的顶点,就不再继续访问其邻接顶点,此条路径不再继续。 如果该顶点是目的顶点,则将该条路径上之前访问的包括此次访问的顶点全部输出,显示所找到的一条简单路径。之后将上一个顶点置为0观察是否还有其余临点,如果有继续查找,如果没有则返回上一个顶点置为0,继续深度优先思想查找。

程序代码

/ **
  *@author ZhangManyuan
  */


import java.util.List;
import java.util.ArrayList;
public class DepthFirstSearch {
    private static void dfs_rec(ArrayList<ArrayList<Integer>> adjLists, boolean[] visited, int v, int d,
            List<Integer> path) {
        visited[v] = true;
        path.add(v);
        if (v == d) {
            for (int i = 0; i < path.size(); i++) {
                System.out.print(path.get(i));
            }
            System.out.println("");
        }
        else {
            for (int w : adjLists.get(v)) {
                if (!visited[w]) {
                    dfs_rec(adjLists, visited, w, d, path);
                }
            }
        }
        path.remove(path.size() - 1);
        visited[v] = false;
    }

    public static void dfs(ArrayList<ArrayList<Integer>> adjLists, int s, int d) {
        int n = adjLists.size();
        boolean[] visited = new boolean[n];

        List<Integer> path = new ArrayList<Integer>();
        int path_index = 0; 
        dfs_rec(adjLists, visited, s, d, path);
    }

    public static void main(String[] args) {

        ArrayList<ArrayList<Integer>> adjLists = new ArrayList<ArrayList<Integer>>();
        final int n = 8;

        for (int v = 0; v < n; v++) {
            adjLists.add(new ArrayList<Integer>());
        }
        adjLists.get(0).add(1);
        adjLists.get(0).add(2);
        // ---------
        adjLists.get(1).add(0);
        adjLists.get(1).add(3);
        adjLists.get(1).add(4);
        // ---------
        adjLists.get(2).add(0);
        adjLists.get(2).add(5);
        adjLists.get(2).add(6);
        // ---------
        adjLists.get(3).add(1);
        adjLists.get(3).add(7);
        // ---------
        adjLists.get(4).add(1);
        adjLists.get(4).add(7);
        // ---------
        adjLists.get(5).add(2);
        adjLists.get(5).add(6);
        // ---------
        adjLists.get(6).add(2);
        adjLists.get(6).add(5);
        // ---------    
        adjLists.get(7).add(3);
        adjLists.get(7).add(4);

        dfs(adjLists, 3, 6);
    }
}
程序测试

这里写图片描述

创建邻接表的过程:(往ArrayList<ArrayList<Integer>> adjLists中不断添加结构)

        adjLists.get(0).add(1);
        adjLists.get(0).add(2);
        // ---------
        adjLists.get(1).add(0);
        adjLists.get(1).add(3);
        adjLists.get(1).add(4);
        // ---------
        adjLists.get(2).add(0);
        adjLists.get(2).add(5);
        adjLists.get(2).add(6);
        // ---------
        adjLists.get(3).add(1);
        adjLists.get(3).add(7);
        // ---------
        adjLists.get(4).add(1);
        adjLists.get(4).add(7);
        // ---------
        adjLists.get(5).add(2);
        adjLists.get(5).add(6);
        // ---------
        adjLists.get(6).add(2);
        adjLists.get(6).add(5);
        // ---------    
        adjLists.get(7).add(3);
        adjLists.get(7).add(4);

在这里我们输出3到6之间的所有路径 dfs(adjLists, 3, 6);

实际运行结果

这里写图片描述

实验中产生的问题
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
    at java.util.ArrayList.rangeCheck(Unknown Source)
    at java.util.ArrayList.get(Unknown Source)
    at DepthFirstSearch.main(DepthFirstSearch.java:65)
  • 解决方法:
    显示为ArrayList的角标溢出
    解决办法:经过检查,发现时节点数目输错,致使 adjLists.get(7).add(3)出现错误
总结
  • DFS为遍历图的优秀算法,巧妙利用递归,再加上flag标记,就可以完成寻找两点间所有路径的算法
  • 编程技巧有待提高
  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值