图论

Posted by tianhaoo on April 29, 2021 本文阅读量

图的java实现

邻接矩阵

如果是无向图,那就在n*n的矩阵里存储0和1即可,代表有边和无边。

如果是有向图,那就在矩阵里存权值,权值为正无穷表示没有相应的边。

perceptron

优点:1. 实现简单 2. 可以快速判断两个顶点之间是否存在边 3.可以快速增删边

缺点:如果是稀疏图会比较浪费空间,不适合增删节点

class Graph{
    int vexNum;
    int edgeNum;
    String[] vertices;
    int[][] edges;
    Graph(int vexNum, int edgeNum, String[] vertices, int[][] edges){
        this.vexNum = vexNum;
        this.edgeNum = edgeNum;
        this.vertices = vertices;
        this.edges = edges;
    }
}

邻接表

邻接表是由图顶点和边指针构成的数组,可以按照节点标号(下标)快速随机访问,从顶点出发的所有边都被用单链表串起来。

perceptron

优点:1.存储稀疏图时可以节省空间。 2. 可以动态增删节点

缺点:无法快速判断两个节点是否相邻,增删边比较麻烦

class ArcNode{
    int weight; // 边的权重
    int vexIndex; // 这条边指向的节点 的编号
    ArcNode nextArc;  // 下一条边
    ArcNode(int weight, int adjVex, ArcNode nextArc){
        this.weight = weight;
        this.vexIndex = vexIndex;
        this.nextArc = nextArc;
    }
}

class VNode{
    int index;  // 节点的编号
    String data;  // 节点的数据
    ArcNode firstArc;  // 从这个点出发的第一条边
    VNode(int index, String data, ArcNode firstArc){
        this.index = index;
        this.data = data;
        this.firstArc = firstArc;
    }
}

class Graph{
    int vexNum;
    int arcNum;
    VNode[] vertices;
    Graph(int vexNum, int arcNum, VNode[] vertices){
        this.vexNum = vexNum;
        this.arcNum = arcNum;
        this.vertices = vertices;
    }
}

遍历

深度优先遍历

public class Main {
    public static void main(String[] args) {
        int[][] edges = {
                {0, 1, 1, 0},
                {1, 0, 1, 0},
                {1, 1, 0, 0},
                {0, 0, 0, 0}
        };
        boolean[] visited = new boolean[edges.length];
        for (int i = 0; i < visited.length; i++) {
            visited[i] = false;
        }

        for (int i = 0; i < edges.length; i++) {
            if(!visited[i]){
                traverse(edges, visited, i);
            }
        }


        for (int i = 0; i < visited.length; i++) {
            System.out.println(visited[i]);
        }

    }

    static void traverse(int[][] edges, boolean[] visited, int i){
        if(visited[i]) return;

        visited[i] = true;
        System.out.println(i);

        for(int j=0; j<edges.length; j++){
            if(edges[i][j] != 0){
                traverse(edges, visited, j);
            }
        }

    }
}

最短路径

dijkstra算法

dijkstra算法是一种经典的基于贪心的单源最短路算法,其要求图中的边全部非负


哈密顿回路