zoukankan      html  css  js  c++  java
  • 数据结构(三十)图的邻接矩阵存储结构

      一、邻接矩阵的Java语言代码实现:

      以有向网为例,无向网中矩阵对称,而有向图和无向图原理类似,只是把正无穷换成0,有连接的地方为1即可:

      

    • 类的四种类型枚举类
    package bigjun.iplab.adjacencyMatrix;
    /**
     * 图的四种主要类型的枚举类
     */
    public enum GraphKind {
    
        UDG,    // 无向图
        DG,        // 有向图
        UDN,    // 无向网
        DN,        // 有向网
    }
    • 接口类
    package bigjun.iplab.adjacencyMatrix;
    /**
     * 图的邻接矩阵存储结构接口类
     */
    public interface AdjacencyMatrixGraphINF {
        
        // 创建一个图
        public void createGraph();
        // 返回图中的顶点数
        public int getVexNum();
        // 返回图中的边数
        public int getArcNum();
        // 给定顶点的位置v,返回其对应的顶点值
        public Object getVex(int x) throws Exception;
        // 给定顶点的值vex,返回其在图中的位置
        public int locateVex(Object vex);
        // 返回顶点v的第一个邻接点
        public int firstAdjvex(int v) throws Exception;
        // 返回v相对于w的下一个邻接点
        public int nextAdjvex(int v, int w) throws Exception;
        
    }
    • 实现类:
    package bigjun.iplab.adjacencyMatrix;
    
    import java.util.Scanner;
    
    public class AdjMatGraph implements AdjacencyMatrixGraphINF{
        
        private final static int INFINITY = Integer.MAX_VALUE;    // 表示正无穷
        private GraphKind kind;            // 图的种类标志
        private int vexNum, arcNum;        // 顶点数,边数
        private Object[] vexs;            // 顶点一维数组
        private int[][] arcs;            // 邻接矩阵
        
        // 构造方法1: 构造一个空图
        public AdjMatGraph() {
            this(null, 0, 0, null, null);
        }
        
        // 构造方法2: 构造一个非空图
        public AdjMatGraph(GraphKind kind, int vexNum, int arcNum, Object[] vexs, int[][] arcs) {
            this.kind = kind;
            this.vexNum = vexNum;
            this.arcNum = arcNum;
            this.vexs = vexs;
            this.arcs = arcs;
        }
    
        // 创建图的四种类型中的一种
        public void createGraph() {
            @SuppressWarnings("resource")
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入图的类型代号(UDG(无向图)、DG(有向图)、UDN(无向网)、DN(有向网)):");
            GraphKind kind = GraphKind.valueOf(scanner.next());
            switch (kind) {
            case UDG:
                createUnDirecedGraph();
                return;
            case DG:
                createDirectedGraph();
                return;
            case UDN:
                createUnDirectedNet();
                return;
            case DN:
                createDirectedNet();
                return;
            }
            System.out.println("图已创建完成!");
        }
        
        // 创建无向图
        private void createUnDirecedGraph() {
            @SuppressWarnings("resource")
            Scanner sc = new Scanner(System.in);
            System.out.println("请分别输入图的顶点数,图的边数: ");
            vexNum = sc.nextInt();
            arcNum = sc.nextInt();
            vexs = new Object[vexNum];
            System.out.println("请分别输入图的各个顶点: ");
            for (int i = 0; i < vexNum; i++) {                // 初始化顶点一维数组
                vexs[i] = sc.next();
            }
            arcs = new int[vexNum][vexNum];
            for (int v = 0; v < vexNum; v++) {                // 初始化邻接矩阵,在每个位置都放上0
                for (int u = 0; u < vexNum; u++) {
                    arcs[v][u] = 0;                            
                }
            }
            System.out.println("请输入各个边的两个顶点: ");
            for (int k = 0; k < arcNum; k++) {                // 填入对应位置上的1
                int v = locateVex(sc.next());
                int u = locateVex(sc.next());
                arcs[v][u] = arcs[u][v] = 1;        
            }
        }
        
        // 创建有向图
        private void createDirectedGraph() {
            @SuppressWarnings("resource")
            Scanner sc = new Scanner(System.in);
            System.out.println("请分别输入图的顶点数,图的边数: ");
            vexNum = sc.nextInt();
            arcNum = sc.nextInt();
            vexs = new Object[vexNum];
            System.out.println("请分别输入图的各个顶点: ");
            for (int i = 0; i < vexNum; i++) {                // 初始化顶点一维数组
                vexs[i] = sc.next();
            }
            arcs = new int[vexNum][vexNum];
            for (int v = 0; v < vexNum; v++) {                // 初始化邻接矩阵,在每个位置都放上0
                for (int u = 0; u < vexNum; u++) {
                    arcs[v][u] = 0;
                }
            }
            System.out.println("请输入各个边的两个顶点: ");
            for (int k = 0; k < arcNum; k++) {                // 填入对应的权值
                int v = locateVex(sc.next());
                int u = locateVex(sc.next());
                arcs[v][u] = 1;                                
            }
        }
        
        // 创建无向网
        private void createUnDirectedNet() {
            @SuppressWarnings("resource")
            Scanner sc = new Scanner(System.in);
            System.out.println("请分别输入图的顶点数,图的边数: ");
            vexNum = sc.nextInt();
            arcNum = sc.nextInt();
            vexs = new Object[vexNum];
            System.out.println("请分别输入图的各个顶点: ");
            for (int i = 0; i < vexNum; i++) {                // 初始化顶点一维数组
                vexs[i] = sc.next();
            }
            arcs = new int[vexNum][vexNum];
            for (int v = 0; v < vexNum; v++) {                // 初始化邻接矩阵,在每个位置都放上正无穷
                for (int u = 0; u < vexNum; u++) {
                    arcs[v][u] = INFINITY;
                    arcs[u][u] = 0;
                }
            }
            System.out.println("请输入各个边的两个顶点及其权值: ");
            for (int k = 0; k < arcNum; k++) {                // 填入对应的权值
                int v = locateVex(sc.next());
                int u = locateVex(sc.next());
                arcs[v][u] = arcs[u][v] = sc.nextInt();        // 由于无向网是矩阵对称的,所以在对称的位置填上对应的值
            }
        }
        
        // 创建有向网
        private void createDirectedNet() {
            @SuppressWarnings("resource")
            Scanner sc = new Scanner(System.in);
            System.out.println("请分别输入图的顶点数,图的边数: ");
            vexNum = sc.nextInt();
            arcNum = sc.nextInt();
            vexs = new Object[vexNum];
            System.out.println("请分别输入图的各个顶点: ");
            for (int i = 0; i < vexNum; i++) {                // 初始化顶点一维数组
                vexs[i] = sc.next();
            }
            arcs = new int[vexNum][vexNum];
            for (int v = 0; v < vexNum; v++) {                // 初始化邻接矩阵,在每个位置都放上正无穷
                for (int u = 0; u < vexNum; u++) {
                    arcs[v][u] = INFINITY;
                    arcs[u][u] = 0;
                }
            }
            System.out.println("请输入各个边的两个顶点及其权值: ");
            for (int k = 0; k < arcNum; k++) {                // 填入对应的权值
                int v = locateVex(sc.next());
                int u = locateVex(sc.next());
                arcs[v][u] = sc.nextInt();                    // 有向网不对称
            }
        }
    
        // 返回顶点数
        public int getVexNum() {
            return vexNum;
        }
    
        // 返回边数
        public int getArcNum() {
            return arcNum;
        }
    
        // 返回v表示结点的值
        public Object getVex(int x) throws Exception{
            if (x < 0 && x >= vexNum ) 
                throw new Exception("给定的顶点不存在");
            return vexs[x];
        }
    
        // 返回顶点的值为vex的顶点在顶点数组的位置下标,如果图中不包含值为vex的顶点,则返回-1
        public int locateVex(Object vex) {
            for (int v = 0; v < vexNum; v++) {
                if (vexs[v].equals(vex)) {
                    return v;
                }
            }
            return -1;
        }
    
        // 返回下标为v的顶点的第一个邻接点,即遍历邻接矩阵的第v行,找到之后,返回第v行对应的下标
        public int firstAdjvex(int v) throws Exception {
            if (v < 0 && v >= vexNum ) 
                throw new Exception("给定的顶点不存在");
            for (int j = 0; j < vexNum; j++) {
                if (arcs[v][j] != 0 && arcs[v][j] < INFINITY) {
                    return j;
                }
            }
            return -1;
        }
    
        // 返回下标为v的顶点相对于下标为w的顶点的下一个邻接点,若w是v的最后一个邻接点,则返回-1
        public int nextAdjvex(int v, int w) throws Exception {
            if (v < 0 && v >= vexNum ) 
                throw new Exception("给定的顶点不存在");
            for (int j = w + 1; j < vexNum; j++) {
                if (arcs[v][j] != 0 && arcs[v][j] < INFINITY) {
                    return j;
                }
            }
            return -1;
        }    
    
        public static void main(String[] args) throws Exception {
            AdjMatGraph aMatGraph = new AdjMatGraph();
            aMatGraph.createGraph();
            System.out.println("该类型的图已经创建完成!");
            System.out.println("顶点2的第一个邻接点是: " + aMatGraph.firstAdjvex(2));
            System.out.println("顶点2的相对于顶点0的下一个邻接点是: " + aMatGraph.nextAdjvex(2, 0));
        }
    }
    • 输出:
    请输入图的类型代号(UDG(无向图)、DG(有向图)、UDN(无向网)、DN(有向网)):
    DN
    请分别输入图的顶点数,图的边数: 
    5 6
    请分别输入图的各个顶点: 
    0 1 2 3 4
    请输入各个边的两个顶点及其权值: 
    2 0 2
    1 0 9
    1 2 3
    2 3 5
    3 4 1
    0 4 6
    该类型的图已经创建完成!
    顶点2的第一个邻接点是: 0
    顶点2的相对于顶点0的下一个邻接点是: 3

      

      二、邻接矩阵的创建C语言代码实现:

    #include "stdio.h"    
    #include "stdlib.h"   
    #include "io.h"  
    #include "math.h"  
    #include "time.h"
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    #define MAXVEX 100 /* 最大顶点数,应由用户定义 */
    #define INFINITY 65535
    
    typedef int Status;    /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
    typedef char VertexType; /* 顶点类型应由用户定义  */
    typedef int EdgeType; /* 边上的权值类型应由用户定义 */
    typedef struct
    {
        VertexType vexs[MAXVEX]; /* 顶点表 */
        EdgeType arc[MAXVEX][MAXVEX];/* 邻接矩阵,可看作边表 */
        int numNodes, numEdges; /* 图中当前的顶点数和边数  */
    }MGraph;
    
    /* 建立无向网图的邻接矩阵表示 */
    void CreateMGraph(MGraph *G)
    {
        int i,j,k,w;
        printf("输入顶点数和边数:
    ");
        scanf("%d,%d",&G->numNodes,&G->numEdges); /* 输入顶点数和边数 */
        for(i = 0;i <G->numNodes;i++) /* 读入顶点信息,建立顶点表 */
            scanf(&G->vexs[i]);
        for(i = 0;i <G->numNodes;i++)
            for(j = 0;j <G->numNodes;j++)
                G->arc[i][j]=INFINITY;    /* 邻接矩阵初始化 */
        for(k = 0;k <G->numEdges;k++) /* 读入numEdges条边,建立邻接矩阵 */
        {
            printf("输入边(vi,vj)上的下标i,下标j和权w:
    ");
            scanf("%d,%d,%d",&i,&j,&w); /* 输入边(vi,vj)上的权w */
            G->arc[i][j]=w; 
            G->arc[j][i]= G->arc[i][j]; /* 因为是无向图,矩阵对称 */
        }
    }
    
    int main(void)
    {    
        MGraph G;    
        CreateMGraph(&G);
        
        return 0;
    }
    邻接矩阵的创建
  • 相关阅读:
    高格-一些特点话题【10】批次批号管理
    study Rust-4【所有权】这个太重要了!
    study Rust-3【表达式和函数】
    study Rust-2【环境与配置,随机数】
    unigui的错误delphi clientHeight:property clientheight does not exist【10】
    shr系统进入用户管理
    节点设置必录注意事项
    单据头字段设置必录
    插件强制设置单据体字段必录
    object转换为List<DynamicObject>
  • 原文地址:https://www.cnblogs.com/BigJunOba/p/9247689.html
Copyright © 2011-2022 走看看