图:BFS/DFS java实现

版权声明:本博客为记录本人学习过程而开,内容大多从网上学习与整理所得,若侵权请告知! https://blog.csdn.net/Fly_as_tadpole/article/details/86534520

上一篇博文介绍了BFS和DFS的原理,现在给出其JAVA代码实现;

BFS就是维护一个队列,先依次访问起始点相邻的节点,入队,再访问相邻节点的相邻节点,依次入队出队。

DFS就是利用递归+回溯,直到递归到没有相邻节点可以访问了,就向上回溯。


BFS:

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
/*广度遍历是遍历到某个顶点,然后访问其连接点a,b;接着访问a的连接表,
很自然的,这种数据结构就是HashMap,以顶点为key,保存每个顶点的连接表
*/
public class BFSbak {
    public static void main(String args[])
    {
        BFSbak bb = new BFSbak();
        // s顶点的邻接表
        LinkedList<Character> list_s = new LinkedList<Character>();
        list_s.add('w');
        list_s.add('r');
        LinkedList<Character> list_w = new LinkedList<Character>();
        list_w.add('s');
        list_w.add('i');
        list_w.add('x');
        LinkedList<Character> list_r = new LinkedList<Character>();
        list_r.add('s');
        list_r.add('v');
        LinkedList<Character> list_x = new LinkedList<Character>();
        list_x.add('w');
        list_x.add('i');
        list_x.add('u');
        list_x.add('y');
        LinkedList<Character> list_v = new LinkedList<Character>();
        list_v.add('r');
        LinkedList<Character> list_i = new LinkedList<Character>();
        list_i.add('u');
        list_i.add('x');
        list_i.add('w');
        LinkedList<Character> list_u = new LinkedList<Character>();
        list_u.add('i');
        list_u.add('x');
        list_u.add('y');
        LinkedList<Character> list_y = new LinkedList<Character>();
        list_y.add('u');
        list_y.add('x');
        //建立邻接表
        HashMap<Character, LinkedList<Character>> graph = new HashMap<Character, LinkedList<Character>>();
        //建立邻接表的链表
        graph.put('s', list_s);
        graph.put('w', list_w);
        graph.put('r', list_r);
        graph.put('x', list_x);
        graph.put('v', list_v);
        graph.put('i', list_i);
        graph.put('y', list_y);
        graph.put('u', list_u);
        //建立节点的标识HashMap
        HashMap<Character, Integer> dist = new HashMap<Character, Integer>();
        char start = 's';
        bb.bfs(graph, dist, start);

    }
    /*HashMap<Character,LinkedList<Character>> graph
     * 这个HashMap是用于存放图中每个node的邻接表
     * 表示此映射所维护的键的类型为Character,此映射值的类型为LinkedList<Character>
     * graph 表示将映射关系存放在graph此映射中
     *
     * LinkedList<Character> 表示在此Collection中保持元素类型为Character
     *
     * HashMap<Character,Integer> dist
     * 这个HashMap 是用于存放每个node与距离顶点s的距离的映射关系
     * 表示此映射所维护的键的类型为Character
     * 此映射所维护的值的类型为Integer,dist表示将映射关系存放到dist此映射中
     */

    private void bfs(HashMap<Character, LinkedList<Character>> graph,HashMap<Character, Integer> dist,char start)
    {
//Queue<Character> 表示在此Collection中所保存的元素的类型为Character
        Queue<Character> q=new LinkedList<Character>();
        q.add(start);//将指定元素s插入队列,成功时返回true,如果没有可用空间,则返回illegalStateException

/*put(start,0) start为指定值将要关联的键,0为指定值将要关联的值,
如果start与0的映射关系已存在,则返回并替换旧值0
如果 start与0的映射关系不存在,则返回null
*/
        dist.put(start, 0);

        int i=0;
        while(!q.isEmpty())//
        {
            char top=q.poll();//获取并移除队列的头,返回队列的头,如果队列为空,返回null
            i++;

//dist.get(top) 返回指定键top所映射的值
            System.out.println("The "+i+"th element:"+top+" Distance from s is:"+dist.get(top));
            int d=dist.get(top)+1;//得出其周边还未被访问的节点的距离

/*graph.get(top)如果此映射包含一个满足 (key==null ? k==null : key.equals(k))
的从 k 键到 v 值的映射关系,则此方法返回 v;否则返回 null。(最多只能有一个这样的映射关系。)
for(元素变量:元素集合),如果元素集合中所有元素都已遍历过,则结束此循环,
否则执行for循环里的程序块
*/
            for (Character c : graph.get(top))
            {

// containskey(key) 如果此映射包含对于指定键key的映射关系,则返回true
                if(!dist.containsKey(c))//如果dist中还没有该元素说明还没有被访问
                {
/*关联指定键c与指定值d,如果关联关系已存在,则替换旧值d,返回旧值d,
如果无映射关系,则返回null*/
                    dist.put(c, d);
                    q.add(c); //将指定元素c插入队列,成功时返回true,如果没有可用空间,则返回illegalStateException
                }
            }
        }
    }
}

DFS:

/**
 * 建立链表节点
 */
class Node {
    int x;
    Node next;
    public Node(int x) {
        this.x = x;
        this.next = null;
    }
}
public class BinaryTree{
    public Node first;  //左孩子
    public Node last;   //右孩子

    //保存访问过的节点值
    public static int run[] = new int[9];
    //建立二叉树节点数组
    public static BinaryTree head[] = new BinaryTree[9];

    /**
     * 访问起始某点,打上标识表示已经访问;再访问这个点的邻接点,在访问这个点的邻接点的邻接点。。一直递归下去,
     * 直到没有了邻接点就返回上层继续此操作;每次访问之后就打上标识表示已经访问过;最后找到所有的节点;
     * @param current
     */
    public static void dfs(int current) {
        run[current] = 1;
        System.out.print("[" + current + "]");

        while (head[current].first != null) {
            if(run[head[current].first.x] == 0) { //如果顶点尚未遍历,就进行dfs递归,访问后就是1啦!!!!
                dfs(head[current].first.x);
            }
            head[current].first = head[current].first.next;
        }
    }

    //判断当前节点是否为空
    public boolean isEmpty() {
        return first == null;
    }
    public void print() {
        Node current = first;
        while(current != null) {
            System.out.print("[" + current.x + "]");
            current = current.next;
        }
        System.out.println();
    }
    
    //插入所有当前节点的所有邻接点;
    public void insert(int x) {
        Node newNode = new Node(x);
        if(this.isEmpty()) {
            first = newNode;
            last = newNode;
        }
        else {
            last.next = newNode;
            last = newNode;
        }
    }

    
    public static void main(String[] args) {
        
        //这此创建不同于上次的邻接表的创建;这次是直接根据图然后来写出节点对的组合,一对表示是连接在一起的邻接点;
        int Data[][] = { {1,2}, {2,1}, {1,3}, {3,1}, {2,4}, {4,2},
                {2,5}, {5,2}, {3,6}, {6,3}, {3,7}, {7,3}, {4,5}, {5,4},
                {6,7}, {7,6}, {5,8}, {8,5}, {6,8}, {8,6} };
        int DataNum;
        int i,j;
        System.out.println("图形的邻接表内容为:");
        for(i=1;i<9;i++) {
            run[i] = 0;
            head[i] = new BinaryTree();
            System.out.print("顶点" + i + "=>");
            for (j=0;j<20;j++) {
                if(Data[j][0] == i) {
                    DataNum = Data[j][1];
                    head[i].insert(DataNum);
                }
            }
            head[i].print();
        }

        System.out.println("深度优先遍历顶点:");
        dfs(1);
        System.out.println("");
    }
}

猜你喜欢

转载自blog.csdn.net/Fly_as_tadpole/article/details/86534520