DFS和BFS(无向图)Java实现

package practice;

import java.util.Iterator;
import java.util.Stack;

import edu.princeton.cs.algs4.*;

public class TestMain {
    public static void main(String[] args) {
        Graph a = new Graph(6);
        a.addEdge(2, 4);
        a.addEdge(2, 3);
        a.addEdge(1, 2);
        a.addEdge(0, 5);
        a.addEdge(0, 1);
        a.addEdge(0, 2);
        a.addEdge(3, 4);
        a.addEdge(3, 5);
        System.out.println(a);

        DisposeMap df = new DisposeMap(a);
        /*df.dfs(0);
        System.out.println(df.hasPathTo(1));
        System.out.println(df.hasPathTo(2));
        Stack<Integer> aStack = df.pathTo(1);
        while (!aStack.isEmpty()) {
            System.out.print(aStack.pop() + "->");
        }
        System.out.println("end");*/

        df.bfs(0);
        for (int i = 0; i < 6; i++) {
            System.out.println(df.marked(i));
        }
        Stack<Integer> aStack = df.pathTo(4);
        while (!aStack.isEmpty()) {
            System.out.print(aStack.pop() + "->");
        }
        System.out.println("end");
    }
}

/*
 * 图处理dispose
 */
class DisposeMap {
    private boolean[] marked; //将已经搜素过的节点储存为true
    private int count = 0;
    private Graph G;
    private int s; //起点
    private int[] edgeTo; //edgeTo[w] = v,w为图中的节点,v为它的父节点

    public DisposeMap(Graph G) {
        this.G = G;

        marked = new boolean[G.V];
        edgeTo = new int[G.V];
        for (int i = 0; i < marked.length; i++) {
            marked[i] = false;
        }
    }
    /*
     * 深度优先搜索,储存以s为起点所能到达的所有点
     */
    public void dfs(int s) {
        marked[s] = true;

        count++;
        System.out.println("Search" + s);
        for (Integer b : G.adj(s)) { //搜索一个节点的相邻的第一个没有被标记过的节点
            if (marked[b] == false) { //如果没有搜索过这个节点,就搜索它
                edgeTo[b] = s;
                dfs(b);
            }
        }
    }
    /*
     * 广度优先搜索
     */
    public void bfs(int s) {
        edu.princeton.cs.algs4.Queue<Integer> queue = new Queue<Integer>();
        queue.enqueue(s);
        marked[s] = true;

        while (!queue.isEmpty()) {
            Integer temp = queue.dequeue();
            for (Integer b : G.adj(temp)) { //搜索一个节点的所有的相邻的节点
                if (marked[b] == false) { //如果没有搜索过这个节点,就搜索它
                    queue.enqueue(b);
                    edgeTo[b] = temp;
                    marked[b] = true;
                }
            }
        }
    }
    /*
     * 查看某点是否被标记
     */
    public boolean marked(int w) { return marked[w];}
    /*
     * 搜索了几个点
     */
    public int count() { return count;}
    /*
     * 是否存在s到v的路径
     */
    public boolean hasPathTo(int v) {
        return marked(v);
    }
    /*
     * s到v的路径,有则返回一个Stack,没有则返回null
     */
    public Stack<Integer> pathTo(int v) {
        Stack<Integer> a = new Stack<Integer>();
        for (int i = v; i != s; i = edgeTo[i])
            a.push(i);
        a.push(s);
        return a;
    }
}

/*
 * 图
 */
class Graph {
    Bag<Integer>[] graph; //这里使用背包的数组,邻借表
    int V;
    int E;

    public Graph(int V) {
        this.V = V;
        graph = (Bag<Integer>[]) new Bag[V];
        for (int i = 0; i < graph.length; i++) {
            graph[i] = (Bag<Integer>) new Bag();
        }
    }
    /*
     * 返回顶点数
     */
    public int V() { return V;}
    /*
     * 返回边数
     */
    public int E() { return E;}
    /*
     * 向图中添加一条边
     */
    public void addEdge(int v, int w) {
        graph[v].add(w);
        graph[w].add(v);
        E++;
    }
    /*
     * 和v相邻的所有顶点
     */
    public Iterable<Integer> adj(int v) {
        return graph[v];
    }
    /*
     * 计算v的度数
     */
    public static int degree(Graph G, int v) {
        int degree = 0;
        for (Integer bag : G.graph[v]) degree++;
        return degree;
    }
    @Override
    public String toString() {
        String s = V + " vertices, " + E + " edges\n";
        for (int v = 0; v < V; v++) {
            s += v + ": ";
            for (Integer integer : this.adj(v)) {
                s += integer + " ";
            }
            s += "\n";
        }
        return s;
    }
}

/*
 * 背包
 */
class Bag<T> implements Iterable<T> {
    Node first;

    private class Node {
        T value;
        Node next;
    }

    public void add(T value) {
        Node oldfirst = first;
        first = new Node();
        first.value = value;
        first.next = oldfirst;
    }

    public void delete(T value) {

    }

    @Override
    public Iterator<T> iterator() {
        return new BagIterator();
    }

    private class BagIterator implements Iterator<T> {
        Node node = first;

        @Override
        public boolean hasNext() {
            return node != null;
        }

        @Override
        public T next() {
            T tempt = node.value;
            node = node.next;
            return tempt;
        }
    }
}

代码中的无向图

图的储存-邻接表示意图

时间: 2024-11-05 07:13:04

DFS和BFS(无向图)Java实现的相关文章

Clone Graph leetcode java(DFS and BFS 基础)

题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each n

数据结构(11) -- 邻接表存储图的DFS和BFS

/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS /////////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> using namespace std; //图的邻接表表示法

hdu 4707 Pet(dfs,bfs)

Pet Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1548    Accepted Submission(s): 733 Problem Description One day, Lin Ji wake up in the morning and found that his pethamster escaped. He sear

数据结构(12) -- 图的邻接矩阵的DFS和BFS

//////////////////////////////////////////////////////// //图的邻接矩阵的DFS和BFS //////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> #define MaxVertexNum 100 //最大顶点数 //#define INFINI

数据结构基础(21) --DFS与BFS

DFS 从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈). //使用邻接矩阵存储的无向图的深度优先遍历 template <typename Type> void Graph<Type>::DFS() { stack<int> iStack; showVertex(0); vertexList[0]->wasVisted = true; iStack.push

图的两种存储(邻接矩阵和邻接表)和两种遍历(DFS和BFS)

图的表示有很多,形式不固定,我暂时先记录我已经懂了的,能写的两种即大多数人应该都知道的邻接矩阵和邻接表. 邻接矩阵: 这里的邻接矩阵和离散数学说的有一点不同,至少有向图的邻接矩阵不同(离散书上的有向图的邻接矩阵求法到是有点像求任意两点的最短路径的Floyd算法) 以上都是(我现有知识认为的)废话: 重点 : G : 表示图: Nv:表示图的点数: Ne:表示图的边数: 邻接矩阵 即是一个 Nv * Nv 的矩阵,矩阵是用来储存  权值的(如果是带权图且有边的话),如果是无权图的的话,如果两顶点有

图的DFS与BFS遍历

一.图的基本概念 1.邻接点:对于无向图无v1 与v2之间有一条弧,则称v1与v2互为邻接点:对于有向图而言<v1,v2>代表有一条从v1到v2的弧,则称v2为v1的邻接点. 2.度:就是与该顶点相互关联的弧的个数. 3.连通图:无向图的每个顶点之间都有可达路径,则称该无向图为连通图.有向图每个顶点之间都有<v1,v2>和<v2,v1>,则称此有向图为强连通图. 二.存储结构 1.邻接矩阵存储(Adjacency Matrix) 对无权图,顶点之间有弧标1,无弧标0:

学习笔记:图的DFS和BFS的两种搜索办法

  在学习图结构的过程中,DFS和BFS是两种不同的遍历方式,其寻找元素具有不同的优点和缺陷. BFS被称作广度优先算法, 在遍历整个图的过程中,BFS将采用入队的方式进行,值得一提的是,这和树结构中的层序遍历有很大的相似之处. 在层序遍历中,将父亲节点入队后,在父亲节点出队后,将其儿子节点入队. 同理在图的BFS遍历中,先让BFS的首元素入队,在收元素入队后将他的儿子节点入队,放能够实现BFS搜索,他们的整体思想是一样的. 1 void TraversalGraph_BFS(LGraph Gr

递归,回溯,DFS,BFS的理解和模板【摘】

递归:就是出现这种情况的代码: (或者说是用到了栈) 解答树角度:在dfs遍历一棵解答树 优点:结构简洁缺点:效率低,可能栈溢出 递归的一般结构: 1 void f() { 2 if(符合边界条件) { 3 /////// 4 return; 5 } 6 7 //某种形式的调用 8 f(); 9 } 回溯:递归的一种,或者说是通过递归这种代码结构来实现回溯这个目的.回溯法可以被认为是一个有过剪枝的DFS过程.解答树角度:带回溯的dfs遍历一棵解答树回溯的一般结构: 1 void dfs(int