图(无向连通无权图)-广度优先搜索
public class Queue { private final int SIZE=20;//列队数量 private int [] queArray;//存数据的数组 private int front ;//用于记录队列的头部(为了删除) private int rear;//用于记录队列的尾部(为了增加) public Queue() { queArray=new int[SIZE];//初始化队列的数据数组 front =0;//初始化队列的头部 rear=-1;//初始化队列的尾部 } public void insert(int j) {//对尾添加一个元素 if(rear==SIZE-1) rear=-1;//判断如果标记队列尾部的数字等于SIZE-1,说明数组已经满了,从头开始 queArray[++rear]=j;//存入数据 } public int remove() {//删除数据,并返回 int temp=queArray[front++]; //获取删除掉的数据 if(front==SIZE)//判断如果删到了最后一个(意思是删完了,就恢复到最终状态,从头开始) front=0; return temp; } public boolean isEmpty() { return (rear+1==front); } }
//图的顶点 public class Vertex { public char label;//顶点的标识符 public boolean wasVisited;//顶点有无被访问的标志 public Vertex(char lab) {//初始化顶点(属性) label=lab; wasVisited=false; } }
public class Graph { private final int MAX_VERTS=20;//最大顶点数 private Vertex[] vertexList;//顶点数组 private int [][]adjMat;//顶点关系的领接矩阵(邻接矩阵的每行或者每列的位置跟顶点数组是对应的) private int nVerts;//当前顶点个数 private Queue theQueue;//列队,用于遍历的工具 public Graph() {//初始化图 vertexList=new Vertex[MAX_VERTS]; //初始化顶点数组 adjMat=new int [MAX_VERTS][MAX_VERTS] ;//初始化邻接矩阵 for(int j=0;j<MAX_VERTS;j++) for(int i=0;i<MAX_VERTS;i++) adjMat[i][j]=0; nVerts=0;//初始化当前顶点个数 theQueue=new Queue();//建立列队对象 } //向顶点数组中添加顶点对象 public void addVertex(char lab) { vertexList[nVerts++]=new Vertex(lab);//建立lab对象,往数组内添加 } //添加边(向邻接矩阵中改变数据为1) public void addEdge(int start,int end) { //因为是无向图所以(i,j)(j,i)都要添加1 adjMat[start][end]=1; adjMat[end][start]=1; } //打印顶点数组,根据获取的顶点数组的下标值,打印顶点 public void displayVertex(int v) { System.out.print(vertexList[v].label); } //广度优先搜索,遍历顶点数组中的每个字符 public void bfs() { vertexList[0].wasVisited=true;//访问第一个顶点 displayVertex(0);//输出第一个顶点 theQueue.insert(0);//将第一个顶点的下标放入栈中(遍历的初始化) int v2; while(!theQueue.isEmpty()) { int v1=theQueue.remove();//从队头部取出一个数据 while((v2=getAdjUnvisitedVertex(v1))!=-1)//取出该顶点的所有邻接顶点 { vertexList[v2].wasVisited=true; displayVertex(v2); theQueue.insert(v2); } } for(int j=0;j<nVerts;j++)//将定点数组中的顶点状态还原 vertexList[j].wasVisited=false; } //返回当前顶点是否有相邻的顶点(只找一个),并且是没有访问过的.找到了就返回顶点的数组下标,没找到就返回-1 public int getAdjUnvisitedVertex(int v) {//v为顶点数组下标 for(int j=0;j<nVerts;j++)//遍历邻接矩阵的当前行 if(adjMat[v][j]==1&&vertexList[j].wasVisited==false)//邻接矩阵的每行每列的位置跟顶点数组是对应的 //判断某顶点跟当前顶点是否有关系,并且没有访问过的 return j; return -1; } }
public class Test { public static void main(String[] agrs) { Graph theGraph=new Graph();//创建一个图 theGraph.addVertex('A');//添加顶点 theGraph.addVertex('B');//添加顶点 theGraph.addVertex('C');//添加顶点 theGraph.addVertex('D');//添加顶点 theGraph.addEdge(0, 1);//添加边 theGraph.addEdge(0, 2);//添加边 theGraph.addEdge(0, 3);//添加边 theGraph.addEdge(1, 3);//添加边 theGraph.bfs(); } }
广度优先搜索:是取出和放入的操作。将队列中的一个值删除并取出,若有邻接顶点,则放入所有的顶点入队列。如此循环