一、图

1. 图的存在意义

image.png

2. 图的表示方式

image.png
image.png

3. 代码实现

image.png
step1: ArrayList vertexList; //存储顶点集合
step2: int[][] 二维矩阵存储关系
step3: int numberOfEdges; //边的数目

  1. import java.util.ArrayList;
  2. import java.util.Arrays;
  3. public class GraphDemo {
  4. private ArrayList<String> vertexList; //存储顶点集合
  5. private int[][] edges;// 存储图对应的零阶矩阵
  6. private int numberOfEdges; //边的数目
  7. public static void main(String[] args) {
  8. int n=5;
  9. String[] vertexValue = {"a","b","c","d","e"};
  10. // 创建图对象
  11. GraphDemo graph = new GraphDemo(5);
  12. for (String vertex : vertexValue) {
  13. graph.insertVertex(vertex);
  14. }
  15. // 添加边
  16. graph.insertEdge(0, 1, 1);
  17. graph.insertEdge(0, 2, 1);
  18. graph.insertEdge(1, 2, 1);
  19. graph.insertEdge(1, 3, 1);
  20. graph.insertEdge(1, 4, 1);
  21. graph.showGraph();
  22. }
  23. /**
  24. *
  25. * @param n 矩阵的维度
  26. */
  27. public GraphDemo(int n) {
  28. // 初始化矩阵和arrayList
  29. edges = new int[n][n];
  30. vertexList= new ArrayList<String>(n); // 放N个数据进去
  31. numberOfEdges=0;
  32. }
  33. // 返回节点的个数
  34. public int getNumberOfVertex(){
  35. return vertexList.size();
  36. }
  37. // 得到边的数目
  38. public int getNumberOfEdges(){
  39. return numberOfEdges;
  40. }
  41. // 返回节点下标为i的点对应的数据
  42. public String getValueByVertexIndex(int i){
  43. return vertexList.get(i);
  44. }
  45. // 显示图的矩阵--》遍历二维数组
  46. public void showGraph(){
  47. for(int[] link:edges){
  48. System.out.println(Arrays.toString(link));
  49. }
  50. }
  51. // 返回v1和v2的权值
  52. public int getWeight(int v1, int v2){
  53. return edges[v1][v2];
  54. }
  55. /**
  56. *
  57. * @param vertex 插入顶点,其名称为vertex
  58. */
  59. public void insertVertex(String vertex){
  60. vertexList.add(vertex);
  61. }
  62. /**
  63. *
  64. * @param v1 表示点的下标,即第几个顶点,顶点的下标
  65. * @param v2 表示点的下标,即第几个顶点,顶点的下标
  66. * @param weight 点之间的权值
  67. */
  68. public void insertEdge(int v1, int v2, int weight){
  69. edges[v1][v2]=weight;
  70. edges[v2][v1]=weight;
  71. numberOfEdges++;
  72. }
  73. }

4. 图的深度优先算法(DFS)

1. 过程解析image.png

2. 代码解析

step1: 获取第一个邻接节点—-即当前行的第一个元素

  1. /**
  2. *
  3. * @param index 在二维数组中的行号, j代表的是二维数组中的列号
  4. * @return 当前行的第多少列
  5. */
  6. public int getFirstNeighbor(int index){
  7. for(int j=0;j<vertexList.size();j++){
  8. if(edges[index][j]>0){
  9. return j;
  10. }
  11. }
  12. return -1;
  13. }

step2: 获取当前行当前元素的下一个邻接节点

  1. // 根据前一个邻接节点的下标,获取下一个邻接节点
  2. public int getNextNeighbor(int v1,int v2){
  3. for(int j=v2+1;j<vertexList.size();j++){
  4. if(edges[v1][j]>0){
  5. return j;
  6. }
  7. }
  8. return -1;
  9. }

step3: 深度遍历

  1. /**
  2. * 传进来的是二维数组的行
  3. * @param isVisted 如果已经访问过,则加入到该链表中
  4. * @param i 节点的下标,即二维数组中的行
  5. */
  6. public void dfs(boolean[] isVisted, int i){
  7. System.out.printf("当前第%s个节点已经被访问", i);
  8. isVisted[i]=true;
  9. // 已当前节点i的第一个邻接节点w
  10. int w = getFirstNeighbor(i); // 还是第I行,w列
  11. while(w!=-1){
  12. // 有邻接节点
  13. if(!isVisted[w]){
  14. // 没有访问就可以正常访问
  15. dfs(isVisted, w);
  16. }
  17. w=getNextNeighbor(i, w);
  18. }
  19. }
  20. // 对dfs进行重载,遍历所有的节点并进行dfs
  21. public void dfs(){
  22. for (int i = 0; i < getNumberOfVertex(); i++) {
  23. if(!isVisted[i]){
  24. dfs(isVisted, i);
  25. }
  26. }
  27. }

5. 广度优先遍历(BFS)