DFS和BFS

深度优先搜索DFS

  • 深度优先搜索,是从图中的一个顶点出发,每次遍历当前访问顶点的临界点,一直到访问的顶点没有未被访问过的临界点为止。然后采用依次回退的方式,查看来的路上每一个顶点是否有其它未被访问的临界点。访问完成后,判断图中的顶点是否已经全部遍历完成,如果没有,以未访问的顶点为起始点,重复上述过程。
  • 深度优先搜索是一个不断回溯的过程,类似树的先序遍历。
  • 可以采用递归或者栈来实现。
图的深度优先搜索
public class DFSTraverse{
	
	//图的邻接矩阵

	// 记录被访问顶点
    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;

	//深度优先搜索
	public void DFSTra(){
		verStatus = new boolean[vertexsNum];
		for(int i = 0; i < vertexsNum; i++){
			if(verStaus[i] == false){
				DFS(i);
			}
		}
	}

	public void DFS(int i){
		verStatus[i] = true;
		for(int j = firstAdjVex(i); j >= 0; j = nextAdjVex(i, j)){
			if(!verStaus[j]){
				DFS(j);
			}
		}
	}

// 返回与i相连的第一个顶点
    private int firstAdjVex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }
	
	// 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = k + 1; j < vertexsNum; j++) {
            if (edges[i][j] == 1) {
                return j;
            }
        }
        return -1;
    }
}
实际问题:
  • 李白打酒

    一天,李白提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
    无事街上走,提壶去打酒。
    逢店加一倍,遇花喝一斗。
    这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。
    请计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少?请计算出所有可能方案的个数。

    public void dfs(int shop,int flower,int liquor){
        if(shop == 0 && flower == 0 && liquor == 1){    //出口 
            answer++;
        } 
        //枚举可能情况 
        //遇到店,店的数目-1,酒加倍
        if(shop > 0) 
        	dfs(shop - 1, flower, liquor * 2);
        //遇到花,花的数目-1,酒-1
        if(flower > 0)  
        	dfs(shop, flower-1, liquor - 1);
    }
    

广度优先搜索BFS

  • 从图中的某一顶点出发,遍历每一个顶点时,依次遍历其所有的邻接点,然后再从这些邻接点出发,同样依次访问它们的邻接点。按照此过程,直到图中所有被访问过的顶点的邻接点都被访问到。
  • 借助队列的先进先出(前一个节点出队,与他邻接的点全部进队)。
  • 类似于树的层次遍历。
图的广度优先搜索
public class BFSTraverse {

    private boolean[] verStatus;
    // 顶点个数
    private int vertexsNum = vertexs.length;
 
    // 广搜
    private void BFS() {
        verStatus = new boolean[vertexsNum];
        Queue<Integer> temp = new LinkedList<Integer>();
        for (int i = 0; i < vertexsNum; i++) {
            if (!verStatus[i]) {
                verStatus[i] = true;
                temp.offer(i);
                while (!temp.isEmpty()) {
                    int j = temp.poll();
                    for (int k = firstAdjvex(j); k >= 0; k = nextAdjvex(j, k)) {
                        if (!verStatus[k]) {
                            verStatus[k] = true;
                            temp.offer(k);
                        }
                    }
                }
            }
        }
    }
 
    // 返回与i相连的第一个顶点
    private int firstAdjvex(int i) {
        for (int j = 0; j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
 
    // 返回与i相连的下一个顶点
    private int nextAdjvex(int i, int k) {
        for (int j = (k + 1); j < vertexsNum; j++) {
            if (edges[i][j] > 0) {
                return j;
            }
        }
        return -1;
    }
}

【参考文档】
Java实现图的遍历(深搜与广搜)
深度优先搜索(DFS、深搜)和广度优先搜索(BFS、广搜)
DFS(深搜)算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值