广度优先结果:
深度优先结果:
代码整理:
public class Graph {
private int vertexSize;//顶点数量
private int[] vertexs;//顶点数组
private int[][] matrix; //矩阵
private static final int MAX_WEIGHT=1000;
//
private boolean[] isVisited;
//初始化顶点数量、二维矩阵和顶点数组
public Graph(int vertextSize){
this.vertexSize=vertextSize;
matrix=new int[vertexSize][vertexSize];
vertexs=new int[vertextSize];
for(int i=0;i<vertextSize;i++){
vertexs[i]=i;
}
isVisited=new boolean[vertexSize];
}
public int[] getVertexs() {
return vertexs;
}
public void setVertexs(int[] vertexs) {
this.vertexs = vertexs;
}
/*
* 根据下标获取指定顶点,然后求得指定顶点的出度
* (出度看二维矩阵的横排) (求入度看二维矩阵的纵排)
*/
public int getOutDegree(int index){
int degree=0;
//遍历得到权值
for(int j=0;j<matrix[index].length;j++){//v0->v0 v0>v1 v0->v2 v0->v3 v0->v4
int weight=matrix[index][j];
if(weight != 0 && weight != MAX_WEIGHT){ //说明该节点是有度的
degree++;
}
}
return degree;
}
/*
* 获取顶点的入度 (求入度看二维矩阵的纵排)
*/
public int getInDegree(int index){
int degree=0;
for(int k=0;k<matrix[index].length;k++){
int weight = matrix[k][index];
if(weight != 0 && weight != MAX_WEIGHT){
degree++;
}
}
return degree;
}
/*
* 获取两个顶点之间的权值
*/
public int getWeight(int v1,int v2){
int weight=matrix[v1][v2];
return weight == 0 ? 0 : (weight == MAX_WEIGHT ? -1 : weight);
}
/*
* 获取某个顶点的第一个临节点
*/
public int getFirstNeighbor(int index){
for(int j=0;j<vertexSize;j++){
if(matrix[index][j] > 0 && matrix[index][j]<MAX_WEIGHT){
return j;
}
}
return -1;
}
/*
* 上一步骤中获取到了某个顶点的第一个临节点,记录他的下标,然后根据他的下标来取得下一个临节点
* v:表示要找的顶点
* index:表示该顶点相对于哪个临节点去获取下一个临节点
*/
public int getNextNeighbor(int v,int index){
for(int j=index+1;j<vertexSize;j++){
if(matrix[v][j] >0 && matrix[v][j] < MAX_WEIGHT){
return j;
}
} //由v7执行到这里,也就是v7再也没有满足要求的临节点了 return -1
return -1;
}
/*
* 图的深度优先算法
*/
public void depthFirstSearch(int i){
isVisited[i]=true; //第一次进来,则该顶点被访问过
int w = getFirstNeighbor(i); //比如i为0,找到第一个顶点的第一个临节点的下标为w
while(w != -1){ //临节点存在
//继续往下深度遍历
if(!isVisited[w]){ //v0->v1->v2->v3->v4->v5 找v5的临节点,为了防止v5再找到v0
//需要遍历 该顶点
System.out.println("访问到了:"+w+"顶点");
depthFirstSearch(w);
} //以v1举例:v1的第一个临节点为v0,但v0已经被访问过了,于是不执行if语句
//也就是执行下面的语句:根据i节点 经由 w去找i的下一个临节点
w=getNextNeighbor(i, w);
}
}
/*如果图是不连通的,存在有顶点不被遍历的情况,这里通过for循环强制遍历每个顶点
* 对外公开的深度优先遍历
*/
public void depthFirstSearch(){
isVisited=new boolean[vertexSize];
for(int i=0;i<vertexSize;i++){
if(!isVisited[i]){
System.out.println("访问到了: "+i+"顶点");
depthFirstSearch(i);
}
}
isVisited=new boolean[vertexSize];
}
public static void main(String[] args) {
Graph graph = new Graph(9);
int [] a1 = new int[]{0,10,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT};
int [] a2 = new int[]{10,0,18,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,MAX_WEIGHT,12};
int [] a3 = new int[]{MAX_WEIGHT,MAX_WEIGHT,0,22,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,8};
int [] a4 = new int[]{MAX_WEIGHT,MAX_WEIGHT,22,0,20,MAX_WEIGHT,MAX_WEIGHT,16,21};
int [] a5 = new int[]{MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,20,0,26,MAX_WEIGHT,7,MAX_WEIGHT};
int [] a6 = new int[]{11,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,26,0,17,MAX_WEIGHT,MAX_WEIGHT};
int [] a7 = new int[]{MAX_WEIGHT,16,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,17,0,19,MAX_WEIGHT};
int [] a8 = new int[]{MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,16,7,MAX_WEIGHT,19,0,MAX_WEIGHT};
int [] a9 = new int[]{MAX_WEIGHT,12,8,21,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,MAX_WEIGHT,0};
graph.matrix[0] = a1;
graph.matrix[1] = a2;
graph.matrix[2] = a3;
graph.matrix[3] = a4;
graph.matrix[4] = a5;
graph.matrix[5] = a6;
graph.matrix[6] = a7;
graph.matrix[7] = a8;
graph.matrix[8] = a9;
//获取指定顶点的出度
int degree=graph.getOutDegree(2);
System.out.println("V2的出度:"+degree);
int inDegree=graph.getInDegree(2);
System.out.println("V2的入度:"+inDegree);
//获取两个顶点之间的权值
//int value=graph.getWeight(2, 3);
//System.out.println("v2与v3之间的权值为: "+value);
/*
* 图的深度优先遍历
*/
//graph.depthFirstSearch();
/*
* 图的广度优先遍历
*/
graph.broadFirstSearch();
}
/*
* 非连通图情况下 强制遍历
*/
public void broadFirstSearch(){
isVisited=new boolean[vertexSize];
for(int i=0;i<vertexSize;i++){
if(!isVisited[i]){
broadFirstSearch(i);
}
}
}
/*
* 实现广度优先遍历 LinkedList实现了Queue接口
*/
private void broadFirstSearch(int i) {
int u,w;
LinkedList<Integer> queue=new LinkedList<Integer>();
System.out.println("访问到了: "+i+"顶点");
isVisited[i]=true;
queue.add(i); //第一次把v0加到队列
while(!queue.isEmpty()){
u = (Integer)(queue.removeFirst()).intValue();
w = getFirstNeighbor(u);
while(w != -1){
if(!isVisited[w]){
System.out.println("访问到了: "+w+"顶点");
isVisited[w]=true;
queue.add(w);
}
w=getNextNeighbor(u, w);
}
}
}
}