图的遍历

图的深度优先遍历和广度优先遍历

一、算法思想

       对于图的深度优先遍历和树的深度优先遍历相似。不同之处在于,在图中可能出现。所以,如果将树的深度优先遍历算法放到包含环的图中就会造成死循环。因此,需要引入标志位数组用来记录已经遍历过的节点,当已访问过的节点再次出现的时候就跳过。深度优先遍历的主要思想是递归,不断递归当前节点的邻居节点。
       对于图的广度优先遍历,同样需要使用标志位数组用来记录已访问的节点,与深度优先遍历不同,广度优先遍历通过使用队列来代替递归。

二、JAVA实现

深度优先遍历:

public class DepthFirstSearchPath {
    private boolean[] marked;//标记访问数组

    private int[] edgeTo;//标记节点的前位节点

    private  int s;

    public DepthFirstSearchPath(UndirGraph graph,int s){
        marked=new boolean[graph.V];
        this.s=s;
        edgeTo=new int[graph.V];
        dfs(graph,s);
    }
    public void dfs(UndirGraph graph,int s){
        marked[s]=true;

        for (int i:graph.adj(s)){
            if (!marked[i]){
                edgeTo[s]=i;
                dfs(graph,i);
            }
        }
    }
    public boolean hasPathto(int s){
        return marked[s];
    }
    public Iterable<Integer> Pathto(int v){
        if (!hasPathto(v))
            return null;
        Stack<Integer> stack=new Stack<>();
        for (int i=v;i!=s;i=edgeTo[i]){
            stack.push(i);
        }
        stack.push(s);
        return stack;
    }




}

广度优先遍历

public class BreadthFirstSearchPath {
    boolean[] marked;//存储被访问过的节点

    private int s;//存储查询路径的起点

    int[] edgeTo;//存储该节点的前置节点

    public BreadthFirstSearchPath(UndirGraph graph,int s){
        this.s=s;
        marked=new boolean[graph.V];
        edgeTo=new int[graph.V];
        bfs(graph,s);
    }

    public void bfs(UndirGraph graph,int s){
        Queue<Integer> queue=new LinkedList<>();
        queue.offer(s);//将节点加入队列
        marked[s]=true;//将节点设置为已经访问

        while (!queue.isEmpty()){
            int temp=queue.poll();//将队头元素取出
            for (int i:graph.adj(temp)){
                if (!marked[i]){
                    marked[i]=true;
                    edgeTo[i]=temp;
                    queue.offer(i);
                }
            }
        }
    }

    public boolean hasPath(int v){
        return marked[v];
    }

    public Iterable<Integer> Pathto(int v){
        Stack<Integer> stack=new Stack<>();
        if (!hasPath(v))
            return null;
        for (int i=v;i!=s;i=edgeTo[i]){
            stack.push(i);
        }
        stack.push(s);

        return stack;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值