DFS和BFSJava实现

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;
    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-10-31 04:43:30

DFS和BFSJava实现的相关文章

解救小哈——DFS算法举例

一.问题引入 有一天,小哈一个人去玩迷宫.但是方向感不好的小哈很快就迷路了.小哼得知后便去解救无助的小哈.此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈.那么,问题来了... 二.问题的分析 首先我们用一个二维数组来存储这个迷宫,刚开始的时候,小哼处于迷宫的入口处(1,1),小哈在(p,q).其实这道题的的本质就在于找从(1,1)到(p,q)的最短路径. 此时摆在小哼面前的路有两条,我们可以先让小哼往右边走,直到走不通的时候再回到这里,再去尝试另外一个方向. 在这里我们规定一

【BZOJ4942】[Noi2017]整数 线段树+DFS(卡过)

[BZOJ4942][Noi2017]整数 题目描述去uoj 题解:如果只有加法,那么直接暴力即可...(因为1的数量最多nlogn个) 先考虑加法,比较显然的做法就是将A二进制分解成log位,然后依次更新这log位,如果最高位依然有进位,那么找到最高位后面的第一个0,将中间的所有1变成0,那个0变成1.这个显然要用到线段树,但是复杂度是nlog2n的,肯定过不去. 于是我在考场上yy了一下,这log位是连续的,我们每次都要花费log的时间去修改一个岂不是很浪费?我们可以先在线段树上找到这段区间

uva1103(dfs)

UVA - 1103 还是没写好,,看的别人的 1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <cstdlib> 7 #include <stack> 8 #include <cctype> 9 #include <str

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+

蓝桥杯 大臣的旅费_树的最长度_两次DFS

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <functional> #include <vector> using namespace std; const int maxn = 1000000 + 10; const int INF = 10000000

A. The Fault in Our Cubes 暴力dfs

http://codeforces.com/gym/101257/problem/A 把它固定在(0,0, 0)到(2, 2, 2)上,每次都暴力dfs检查,不会超时的,因为规定在这个空间上,一不行,就会早早退出. 这样写起来比较好写. #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <

codeforces717E Paint it really, really dark gray(树上dfs)

题意: 给你一棵树,2e5个节点,每个节点有一种颜色(黑色或粉色) 让你从节点1开始,自由沿边行走,到达节点时会把这个节点的颜色改变 要求你输出任意一条路径使得从节点1出发,所有节点的颜色都变为黑色 思路: 很明显要递归遍历 每到达一个节点就先改变节点的颜色标志并输出当前节点 如果当前到达了叶子节点,则不用进行操作 返回上层节点时再改变节点的颜色标志并输出当前节点,然后判断叶子节点的颜色,如果为粉色,则再到达一次叶子节点再回到当前节点 这样确保当前节点的所有儿子节点都为黑色的 然后就这样一直递归

POJ2488 dfs

A Knight's Journey Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41972   Accepted: 14286 Description Background The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey ar

BZOJ_1016_[JSOI2008]_最小生成树计数_(dfs+乘法原理)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1016 给出一张图,其中具有相同权值的边的数目不超过10,求最小生成树的个数. 分析 生成树的计数有一个什么什么算法... 我真的企图研究了...但是智商捉急的我实在看不懂论文... 所以最后还是写了暴力... 当然暴力也要靠正确的姿势的. 首先来看一个结论: 同一张图的所有最小生成树中,边权值相同的边的数目是一定的. 也就是说,假如某一张图的某一棵最小生成树由边权值为1,1,2,2,2,3的