基于Java实现的图的广度优先遍历算法_java

本文以实例形式讲述了基于Java的图的广度优先遍历算法实现方法,具体方法如下:

用邻接矩阵存储图方法:

1.确定图的顶点个数和边的个数

2.输入顶点信息存储在一维数组vertex中

3.初始化邻接矩阵;

4.依次输入每条边存储在邻接矩阵arc中

输入边依附的两个顶点的序号i,j;
将邻接矩阵的第i行第j列的元素值置为1;
将邻接矩阵的第j行第i列的元素值置为1;

广度优先遍历实现:

1.初始化队列Q
2.访问顶点v;visited[v]=1;顶点v入队Q;
3.while(队列Q非空)

v=队列Q的队头元素出队;
w=顶点v的第一个邻接点
while(w存在)

如果w未被访问,则访问顶点w;visited[w]=1;顶点w入队列Q

w=顶点v的下一个邻接点

实现代码如下:

package com.teradata.lsw.sort;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class BFS {

// 存储节点信息
private Object[] vertices;
// 存储边的信息数组
private int[][] arcs;
// 边的条数
private int vexnum;
// 记录第i个节点是否被访问过
private boolean[] visited;
//构建一个临时链表存已经遍历过的节点
private List<Object> temp = new ArrayList<Object>();

/**
* @param args
*
* @author TD_LSW
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

BFS g = new BFS(8);
Character[] vertices = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
g.addVertex(vertices);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(1, 4);
g.addEdge(3, 5);
g.addEdge(4, 5);
g.addEdge(2, 6);
g.addEdge(2, 7);

System.out.println("图的广度优先遍历:");
g.bfs();
}

// 广度优先遍历实现
private void bfs() {
// TODO Auto-generated method stub
for (int i = 0; i < vexnum; i++) {
visited[i] = false;
}
Queue<Integer> q = new LinkedList<Integer>();
for (int i = 0; i < vexnum; i++) {
if (!visited[i]) {
visited[i] = true;
visit(i);
q.add(i);
while (!q.isEmpty()) {
int j = (Integer) q.remove().intValue();
//判断如果全部遍历完了就不需要循环了
if (temp.size() == vexnum) {
q.removeAll(q);
return;
}
for (int k = this.firstAdjVex(j); k >= 0; k = this
.nextAdjVex(j, k)) {
if (!visited[k]) {
q.add(k);
visited[k] = true;
visit(k);
}
}
}
}
}

}

// 查找下一个节点
public int firstAdjVex(int i) {
for (int j = 0; j < vexnum; j++) {
if (arcs[i][j] > 0)
return j;
}
return -1;
}

public int nextAdjVex(int i, int k) {
for (int j = k + 1; j < vexnum; j++) {
if (arcs[i][j] > 0)
return j;
}
return -1;
}

// 初始化图的边
private void addEdge(int i, int j) {
// TODO Auto-generated method stub
if (i == j)
return;
arcs[i][j] = 1;
arcs[j][i] = 1;

}

// 初始化图的节点
private void addVertex(Object[] object) {
// TODO Auto-generated method stub
this.vertices = object;
}

// 图的初始化
public BFS(int n) {
// TODO Auto-generated constructor stub
vexnum = n;
vertices = new Object[n];
arcs = new int[n][n];
visited = new boolean[n];
for (int i = 0; i < vexnum; i++) {
for (int j = 0; j < vexnum; j++) {
arcs[i][j] = 0;
}
}
}

private void visit(int i) {
// TODO Auto-generated method stub
temp.add(vertices[i]);
System.out.print(vertices[i] + " ");
}

}

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 算法
, 遍历
, 图
广度优先
图的广度优先遍历算法、广度优先遍历算法、树的广度优先遍历算法、java实现广度优先遍历、广度优先遍历,以便于您获取更多的相关知识。

时间: 2024-09-30 01:07:09

基于Java实现的图的广度优先遍历算法_java的相关文章

图的广度优先遍历算法

前言 广度优先遍历算法是图的另一种基本遍历算法,其基本思想是尽最大程度辐射能够覆盖的节点,并对其进行访问.以迷宫为例,深度优先搜索更像是一个人在走迷宫,遇到没有走过就标记,遇到走过就退一步重新走:而广度优先搜索则可以想象成一组人一起朝不同的方向走迷宫,当出现新的未走过的路的时候,可以理解成一个人有分身术,继续从不同的方向走,,当相遇的时候则是合二为一(好吧,有点扯了). 广度优先遍历算法的遍历过程 仍然以上一篇图的深度优先遍历算法的例子进行说明,下面是广度优先遍历的具体过程: 从起点0开始遍历

算法研究:图的广度优先遍历

图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程 就叫做图的遍历(Traverse Graph). 图的遍历方法一般有两种,第一种是我们在前面讲过的<深度优先遍历 (Depth First Search)>,也有称为深度优先搜索,简称为DFS.第二种是广度优先遍历(Breadth  First Search), 也有称为广度优先搜索,简称为BFS.我们在<队列与广度优先搜索>中已经较为详细地讲述了广度优先搜索的策略,这里 不再

二叉树的广度优先遍历算法递归方式实现

问题描述 如题,二叉树的广度优先遍历算法非递归方式的实现是使用队列,依次把每层节点放入队列,在出队,那么能不能用递归方式实现二叉树的广度优先遍历算法呢? 解决方案

邻接表表示的图的广度优先遍历-Breadth First Search Graph

Breadth First Search Graph eryar@163.com 一.简介 广度优先遍历类似于树的按层次遍历过程. 假设从图中某顶点V出发,在访问了V之后依次访问V的各个未曾访问过的邻接顶点,然后分别从这些邻接点出发依次访问它们的邻接点,并使"先被访问的顶点的邻接点"先于"后被访问的顶点的邻接点"被访问,直到图中所有已被访问的顶点的邻接点都被访问到.到此时图中尚有未被访问的顶点,则另选图中一个未曾访问的顶点作为始点,重复上述过程,直到图中所有顶点都被

图的深度优先遍历算法

前言 图的遍历与前面文章中的二叉树遍历还是存在很大区别的.所谓图的遍历指的是从图中的某一个顶点出发访问图中的其余顶点,并且需要保证每个顶点只被访问一次.由于图比二叉树复杂得多,所以前面二叉树的遍历算法在图中是行不通的.因为对于任意一个顶点来讲,都可能与其余的顶点发生连接.如果不对访问的顶点做一些处理,出发重复访问的几率是很高的.因此,一个基本思想是设置一个标记数组,主要用于标记已经被访问过的顶点.图的遍历算法主要有两种:深度优先遍历和广度优先遍历.本篇文章主要介绍的是深度优先遍历算法. 深度优先

基于Java中Math类的常用函数总结_java

Java中比较常用的几个数学公式的总结: //取整,返回小于目标函数的最大整数,如下将会返回-2 Math.floor(-1.8): //取整,返回发育目标数的最小整数 Math.ceil() //四舍五入取整 Math.round() //计算平方根 Math.sqrt() //计算立方根 Math.cbrt() //返回欧拉数e的n次幂 Math.exp(3); //计算乘方,下面是计算3的2次方 Math.pow(3,2); //计算自然对数 Math.log(); //计算绝对值 Mat

基于Java代码实现支付充值的通用流程_java

废话不多说了,直接给大家贴java代码了. 具体代码如下所示: /*支付流程*/ /****Controller.java 代码如下:*/ @RequestMapping(value = "/paySubmit.htm", method = RequestMethod.POST) public ModelAndView paySubmit(HttpServletRequest request, HttpServletResponse response, @RequestParam Ma

基于java涉及父子类的异常详解_java

java中的异常涉及到父子类的问题,可以归纳为一句话:子类的构造函数抛出的异常必须包含父类的异常,子类的方法可以选择抛出"范围小于等于"父类的异常或不抛出异常. 1. 为什么构造函数必须抛出包含父类的异常? 在<thingking in java>中有这么一段话: 异常限制:当覆盖方法时,只能抛出在基类方法的异常说明中列出的那些异常 异常限制对构造器不起作用,你会发现StormyInning的构造器可以抛出任何异常,而不必理会基类构造函数所抛出的异常.然而因为必须构造函数必

基于Java HashMap的死循环的启示详解_java

一.单线程改造为多线程也是个技术活 正如我们看到耗子叔叔博客里写的那样,原来是单线程的应用程序,"后来,我们的程序性能有问题,所以需要变成多线程的,于是,变成多线程后到了线上,发现程序经常占了100%的CPU". 考虑到是淘宝的工程师曝出来的问题,他们的技术基础一般都很扎实,连他们都用错了,所以把单线程改造为多线程并不是想象中的那么简单,我认为. 你可能很不服气地反问,淘宝的工程师又怎么了,单线程改为多线程有什么难的?无非就是应用现有的多线程技术嘛,你看,我有非常强烈的线程安全意识,我