BFS、DFS实现

BFS

package main.java.com.nexta.basic.mapvisit;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @desc: BFS
 * @Author: WangJ
 * @Date: 2018/11/27 10:54
 */
public class BFSVisit {
    //构建领接矩阵
    //1、访问v,借助队列
    //2、假设v最近一层没有访问的节点为v1,v2,v3,v4,依次访问v1,v2,v3,v4未被访问的节点
    //3、重复2,直到没有被访问的领接点为止

    static final int N = 10;
    static int[][] a = {
            {0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
            {1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 1, 1, 1, 0, 0, 0},
            {0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 0, 1, 0, 0, 0},
            {0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
            {0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
            {0, 0, 0, 0, 0, 0, 0, 1, 1, 0}
    };
    static boolean visit[] = new boolean[N];

    static BlockingQueue<Integer> queue = new ArrayBlockingQueue(N);

    public static void BFS(int v) throws Exception {

        System.out.print(v + " ");
        queue.put(v);

        int b, adj;
        while (!queue.isEmpty()) {
            b = queue.poll();
            adj = Adj(b);
            while (adj != 0) {
                if (visit[adj] == false) {
                    System.out.print(adj + " ");
                    visit[adj] = true;
                    queue.put(adj);
                }
                adj = Adj(b);
            }
        }
    }

    public static int Adj(int v) {
        for (int i = 0; i < N; i++) {
            if (a[v][i] == 1 && visit[i] == false) {
                return i;
            }
        }
        return 0;
    }

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < N; i++) {
            if (visit[i] == false)
                BFS(i);
        }

    }
    /*
    先我们要知道使用队列的目的是什么?一般情况下,如果是一些及时消息的处理,并且处理时间很短的情况下是不需要使用队列的,直接阻塞式的方法调用就可以了。
    但是,如果在消息处理的时候特别费时间,这个时候如果有新的消息来了,就只能处于阻塞状态,造成用户等待。这个时候在项目中引入队列是十分有必要的。
    当我们接受到消息后,先把消息放到队列中,然后再用新的线程进行处理,这个时候就不会有消息的阻塞了。下面就跟大家介绍两种队列的使用,一种是基于内存的,一种是基于数据库的。

     首先,我们来看看基于内存的队列。在Java的并发包中已经提供了BlockingQueue的实现,比较常用的有ArrayBlockingQueue和LinkedBlockingQueue,
     前者是以数组的形式存储,后者是以Node节点的链表形式存储。至于数组和链表的区别这里就不多说了。

BlockingQueue 队列常用的操作方法:

      1.往队列中添加元素: add(), put(), offer()

      2.从队列中取出或者删除元素: remove() element()  peek()   poll()  take()

每个方法的说明如下:

      offer()方法往队列添加元素如果队列已满直接返回false,队列未满则直接插入并返回true;

      add()方法是对offer()方法的简单封装.如果队列已满,抛出异常new IllegalStateException("Queue full");

       put()方法往队列里插入元素,如果队列已经满,则会一直等待直到队列为空插入新元素,或者线程被中断抛出异常.

       remove()方法直接删除队头的元素:

       peek()方法直接取出队头的元素,并不删除.

       element()方法对peek方法进行简单封装,如果队头元素存在则取出并不删除,如果不存在抛出异常NoSuchElementException()

       poll()方法取出并删除队头的元素,当队列为空,返回null;

       take()方法取出并删除队头的元素,当队列为空,则会一直等待直到队列有新元素可以取出,或者线程被中断抛出异常

  offer()方法一般跟pool()方法相对应, put()方法一般跟take()方法相对应.日常开发过程中offer()与pool()方法用的相对比较频繁.

     */
}

DFS

package main.java.com.nexta.basic.mapvisit;

/**
 * @desc: DFS
 * @Author: WangJ
 * @Date: 2018/11/27 9:26
 */

public class DFSVisit {
    //1、构建邻接矩阵
    static final int N = 11;
    static int[][] a = {
            {0, 1, 0, 0, 0, 0, 0, 1, 0, 0},
            {1, 0, 1, 1, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 1, 0, 0, 1, 1, 1, 0, 0, 0},
            {0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 0, 1, 0, 0, 0},
            {0, 0, 0, 1, 0, 1, 0, 0, 0, 0},
            {1, 0, 0, 0, 0, 0, 0, 0, 1, 1},
            {0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
            {0, 0, 0, 0, 0, 0, 0, 1, 1, 0}
    };
    static boolean[] visit = new boolean[N];

    //2、递归访问矩阵
    public static void DFS(int v) {
        visit[v] = true;
        System.out.print(v + " ");
        int adj = Adj(v);
        while (adj != 0) {
            if (visit[adj] == false) {
                DFS(adj);
            }
            adj = Adj(v);
        }
    }

    //求领接点
    public static int Adj(int v) {
        for (int i = 0; i < N - 1; i++) {
            if (a[v][i] == 1 && visit[i] == false) {
                return i;
            }
        }
        return 0;
    }

    public static void main(String[] args) {
        for (int i = 0; i < N - 1; i++) {
            if (visit[i] == false) {
                DFS(i);
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值