Java教程

35.图

本文主要是介绍35.图,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.定义变量

private ArrayList<String> vertexList; //存储顶点集合
private int[][] edges; //存储图对应的邻结矩阵
private int numOfEdges; //表示边的数目
//定义给数组boolean[], 记录某个结点是否被访问
private boolean[] isVisited;

 

2.构造器

public Graph(int n) {
   //初始化矩阵和vertexList
   edges = new int[n][n];
   vertexList = new ArrayList<String>(n);
   numOfEdges = 0;
   
}

 

3.得到第一个邻接结点的下标 w 

public int getFirstNeighbor(int index) {
   for(int j = 0; j < vertexList.size(); j++) {
      if(edges[index][j] > 0) {
         return j;
      }
   }
   return -1;
}

 

4.根据前一个邻接结点的下标来获取下一个邻接结点

public int getNextNeighbor(int v1, int v2) {
   for(int j = v2 + 1; j < vertexList.size(); j++) {
      if(edges[v1][j] > 0) {
         return j;
      }
   }
   return -1;
}

 

5.深度优先遍历算法

//i 第一次就是 0
private void dfs(boolean[] isVisited, int i) {
   //首先我们访问该结点,输出
   System.out.print(getValueByIndex(i) + "->");
   //将结点设置为已经访问
   isVisited[i] = true;
   //查找结点i的第一个邻接结点w
   int w = getFirstNeighbor(i);
   while(w != -1) {//说明有
      if(!isVisited[w]) {
         dfs(isVisited, w);
      }
      //如果w结点已经被访问过
      w = getNextNeighbor(i, w);
   }
   
}

 

6.对dfs 进行一个重载, 遍历我们所有的结点,并进行 dfs

public void dfs() {
   isVisited = new boolean[vertexList.size()];
   //遍历所有的结点,进行dfs[回溯]
   for(int i = 0; i < getNumOfVertex(); i++) {
      if(!isVisited[i]) {
         dfs(isVisited, i);
      }
   }
}

 

7.对一个结点进行广度优先遍历的方法

private void bfs(boolean[] isVisited, int i) {
   int u ; // 表示队列的头结点对应下标
   int w ; // 邻接结点w
   //队列,记录结点访问的顺序
   LinkedList<Integer> queue = new LinkedList<Integer>();
   //访问结点,输出结点信息
   System.out.print(getValueByIndex(i) + "=>");
   //标记为已访问
   isVisited[i] = true;
   //将结点加入队列
   queue.addLast(i);
   
   while( !queue.isEmpty()) {
      //取出队列的头结点下标
      u = queue.removeFirst();
      //得到第一个邻接结点的下标 w 
      w = getFirstNeighbor(u);
      while(w != -1) {//找到
         //是否访问过
         if(!isVisited[w]) {
            System.out.print(getValueByIndex(w) + "=>");
            //标记已经访问
            isVisited[w] = true;
            //入队
            queue.addLast(w);
         }
         //以u为前驱点,找w后面的下一个邻结点
         w = getNextNeighbor(u, w); //体现出我们的广度优先
      }
   }
   
} 

 

8.遍历所有的结点,都进行广度优先搜索

public void bfs() {
   isVisited = new boolean[vertexList.size()];
   for(int i = 0; i < getNumOfVertex(); i++) {
      if(!isVisited[i]) {
         bfs(isVisited, i);
      }
   }
}

 

9.返回结点的个数

public int getNumOfVertex() {
   return vertexList.size();
}

 

10.显示图对应的矩阵

public void showGraph() {
   for(int[] link : edges) {
      System.err.println(Arrays.toString(link));
   }
}

 

11.得到边的数目

public int getNumOfEdges() {
   return numOfEdges;
}

12.返回结点i(下标)对应的数据 0->"A" 1->"B" 2->"C"

public String getValueByIndex(int i) {
   return vertexList.get(i);
}

 

13.返回v1和v2的权值

public int getWeight(int v1, int v2) {
   return edges[v1][v2];
}

 

14.插入结点

public void insertVertex(String vertex) {
   vertexList.add(vertex);
}

 

15.添加边

/**
 * 
 * @param v1 表示点的下标即使第几个顶点  "A"-"B" "A"->0 "B"->1
 * @param v2 第二个顶点对应的下标
 * @param weight 表示 
 */
public void insertEdge(int v1, int v2, int weight) {
   edges[v1][v2] = weight;
   edges[v2][v1] = weight;
   numOfEdges++;
}

16.测试

public static void main(String[] args) {
      //测试一把图是否创建ok
      int n = 8;  //结点的个数
      //String Vertexs[] = {"A", "B", "C", "D", "E"};
      String Vertexs[] = {"1", "2", "3", "4", "5", "6", "7", "8"};
      
      //创建图对象
      Graph graph = new Graph(n);
      //循环的添加顶点
      for(String vertex: Vertexs) {
         graph.insertVertex(vertex);
      }
      
      //添加边
      //A-B A-C B-C B-D B-E 
//    graph.insertEdge(0, 1, 1); // A-B
//    graph.insertEdge(0, 2, 1); // 
//    graph.insertEdge(1, 2, 1); // 
//    graph.insertEdge(1, 3, 1); // 
//    graph.insertEdge(1, 4, 1); // 
      
      //更新边的关系
      graph.insertEdge(0, 1, 1);
      graph.insertEdge(0, 2, 1);
      graph.insertEdge(1, 3, 1);
      graph.insertEdge(1, 4, 1);
      graph.insertEdge(3, 7, 1);
      graph.insertEdge(4, 7, 1);
      graph.insertEdge(2, 5, 1);
      graph.insertEdge(2, 6, 1);
      graph.insertEdge(5, 6, 1);

      
      
      //显示一把邻结矩阵
      graph.showGraph();
      
      //测试一把,我们的dfs遍历是否ok
      System.out.println("深度遍历");
      graph.dfs(); // A->B->C->D->E [1->2->4->8->5->3->6->7]
//    System.out.println();
      System.out.println("广度优先!");
      graph.bfs(); // A->B->C->D-E [1->2->3->4->5->6->7->8]
      
   }
这篇关于35.图的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!