图的遍历——广度优先搜索(Breadth First Search)

1.广度优先搜索遍历类似于树的按层次遍历的过程。

假设从图中某顶点V出发,在访问了V之后依次访问V的各个未曾访问过得邻接点,然后分别从这些邻接点出出发,依次访问他们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问。直至图中所有的已被访问的顶点的邻接点都被访问完。若此时图中还有未被访问的顶点,则选一个图中未被访问的顶点做起始点,重复上述广度优先搜索遍历过程,直到所有的顶点被遍历完。

换句话说,广度优先搜索是以v为起始点,由近及远,依次访问和v路径相通且路径长度为1,2,。。。的顶点。

2.以下图为例,做个简单的广度优先搜索的过程

假设以V1顶点为出发点,首先访问V1顶点,然后依次访问V1的邻接点V2,V3,然后以V1的邻接点V2,V3为起始点,分别访问V2的邻接点V4,V5,然后访问V3的邻接点V6,V7;紧接着分别以V4,V5,V6,V7为出发点,首先访问V4的邻接点V8,访问V5的邻接点,V6的邻接点V9,v7的邻接点,此时V8,V9的邻接点都已经被访问完了,此时图的遍历已经结束。

此时的顶点访问顺序为:

V1->V2->V3->V4->V5->V6->V7->V8->V9

3.和深度优先搜索类似,在遍历的过程中也需要一个访问标志数组。并且,为了顺次访问路径长度为2,3的顶点,需附设队列来存储已 被访问的路径长度1,2.。。的顶点;

4.附上代码算法:

example 1: 以队列为辅助

public void BFS1() {
        boolean[] visited = new boolean[mVexs.length];
        for (int i = 0; i < mVexs.length; i++) {
            visited[i] = false;
        }
        Queue<Integer> queue =new LinkedList<>();
        for (int i = 0; i < mVexs.length; i++) {  //遍历各个顶点
            if (!visited[i]) {
                visited[i] = true;
                System.out.println(i + "(" + mVexs[i].data + ")");
                queue.offer(i);//入队列,选取一个顶点开始进行广度优先搜索
            }
            while (queue.isEmpty()) {  //用两个值来表示队列,
                //出队列
                int j=queue.poll();
                ENode node = mVexs[j].firstEdge;
                while (node != null) {
                    if (!visited[node.ivex]) {
                        visited[node.ivex] = true;
                        queue.offer(node.ivex);//入队列
                        System.out.println(i + "(" + mVexs[node.ivex].data + ")");
                    }
                    node = node.nextEdge;
                }
            }

        }
    }

example2:以数组来实现队列的辅助 

 public void BFS() {
        boolean[] visited = new boolean[mVexs.length];
        for (int i = 0; i < mVexs.length; i++) {
            visited[i] = false;
        }
        int head = 0;
        //用两个索引的一个int数组来表示辅助队列,用来存取顶点的位置
        
        int rear = 0;
        int[] queue = new int[mVexs.length];
        for (int i = 0; i < mVexs.length; i++) {  //遍历各个顶点

            if (!visited[i]) {
                visited[i] = true;
                System.out.println(i + "(" + mVexs[i].data + ")");
                queue[rear++] = i;  //入队列,选取一个顶点开始进行广度优先搜索
            }
            while (head != rear) {  //用两个值来表示队列,
                int j = queue[head++]; //出队列
                ENode node = mVexs[j].firstEdge;
                while (node != null) {
                    if (!visited[node.ivex]) {
                        visited[node.ivex] = true;
                        queue[rear++] = node.ivex;  //入队列
                        System.out.println(i + "(" + mVexs[node.ivex].data + ")");

                    }
                    node = node.nextEdge;
                }
            }

        }
    }

5.时间复杂度

分析上述算法,每个顶点至多进一次队列。遍历图的过程实质上是通过边或者弧找邻接点的过程,因此广度优先搜索遍历图的时间复杂度和深度优先搜索遍历相同。两者不同的地方仅在于对顶点访问时间的顺序不同。

转载于:https://my.oschina.net/u/2263272/blog/1610009

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值