• 数据结构知识点(三)——图


     图是由有穷非空集合的顶点和顶点之间的边组成的集合,通常表示为G(V,E),其中G表示一个图,V表示图G中的顶点的集合,E是图G中边的集合。

    • 在线性结构中,每个元素都只有一个直接前驱和一个直接后继,主要用来表示一对一的数据结构。
    • 在树形结构中,数据之间有着明显的父子关系,主要用来表示一对多的数据结构。
    • 在图形结构中,数据之间具有任意关系,图中任意两个数据之间都可能相关,主要用来表示多对多的数据结构。

     1、图的表示方式(存储结构)

      图的表示方式有两种:邻接矩阵和邻接表。

    1.1邻接矩阵

      邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵的行和列表示1~n个点。

      无向图的邻接矩阵,如图:

      有向图的邻接矩阵,如图:

       

      带权图的邻接矩阵,如图:

    1.2 邻接表

      邻接表是指数组和链表相结合的存储方式。邻接表是图的一种链式存储结构,主要解决邻接矩阵中顶点多而边少时浪费空间的问题。

      无向图的邻接表,如图:

      带权图的邻接表,如图:

      data:数据,存储顶点的信息;

      firstedge:指针域,指向边表的第一个结点,即此顶点的第一个邻接点;

      adjvex:邻接点域,存储某顶点的邻接点在顶点表中的下标;

      weight:权重;

      next:存储指向边表中下一个结点的指针。

    1.3 图的代码实现

    (1)实现图的数据结构:

    public class Graph {
        private ArrayList<String> vertexList;//存储顶点集合
        private int[][] edges;//存储图对应的邻接矩阵
        private int numOfEdges;//图中边的数目
         //构造器
        public Graph(int n) {
            edges = new int[n][n];
            vertexList = new ArrayList<String>(n);
            numOfEdges = 0;
        }
        //插入顶点
        public void insertVertex(String vertex){
            vertexList.add(vertex);
        }
        //插入有关系边(A-B,B-C....)
        public void insertEdge(int v1,int v2, int weight){
            edges[v1][v2] = weight;
            edges[v2][v1] = weight;
            numOfEdges++;
        }
        //获得边的数目
        public int getNumOfEdges(){
            return numOfEdges;
        }
        //获得结点个数
        public int getVertexList() {
            return vertexList.size();
        }
        //显示图对应的矩阵
        public void showGraph(){
            for (int[] link:edges){
                System.out.println(Arrays.toString(link));
            }
        }
    }

    (2)实现图:

    //实现图:
    //    A   B   C   D   E
    //A   0   1   1   0   0
    //B   1   0   1   1   1
    //C   1   1   0   0   0
    //D   0   1   0   0   0
    //E   0   1   0   0   0
    
    public class Main {
        public static void main(String[] args) {
            int n = 5;
            String vertexs[] = {"A", "B", "C", "D", "E"};
            Graph graph = new Graph(n);
            for (String vertex : vertexs) {
                graph.insertVertex(vertex);
            }
            //添加边
            graph.insertEdge(0,1,1);
            graph.insertEdge(0,2,1);
            graph.insertEdge(1,2,1);
            graph.insertEdge(1,3,1);
            graph.insertEdge(1,4,1);
            graph.showGraph();
        }
    }

    1.4 图的遍历

      图的遍历指从图中某一顶点出发访遍图中的每个顶点,且使每一个顶点仅被访问一次。图的遍历分为广度优先遍历和深度优先遍历,对无向图和有向图都适用。

    1、深度优先

      图的深度优先搜索,和树的先序遍历比较类似。

    原图:

     

    深度优先遍历,如图:

     访问顺序是:A -> C -> B -> D -> F -> G -> E

    2、广度优先

      广度优先遍历,类似于树的分层遍历算法。

    广度优先遍历,如图:

     访问顺序是:A -> C -> D -> F -> B -> G -> E

    1.5 位图

      位图(bitmap)通常基于数组实现。就是用每一位来存放某种状态,适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在的。

      位图在内部维护了一个M*N维的数组char[M][N],在这个数组里面每个字节占8位,因此可以存储M*N*8个数据。

    例如要存储的数据范围为0~15,只需分配使用M=1,N=2的数据进行存储,具体的数据结构,如图:

     数据为【5,1,7,15,0,4,6,10】,则存入这个结构中的情况为,如图:

  • 相关阅读:
    安卓学习记录(四)——体温表APP
    2012ACM/ICPC亚洲区域赛成都赛区 总结
    poj 1011 Sticks(dfs+剪枝)
    uva 10891 Game of Sum (DP水题)
    poj 1077 Eight (bfs+康拓展开,A*&&IDA*算法)
    USACO Shaping Regions(离散化)
    poj 2741 Colored Cubes(dfs暴力枚举)
    LightOJ 1400 Employment (Stable Marriage)
    uva 10859 Placing Lampposts / Tree DP
    poj 1062 昂贵的聘礼(dfs+剪枝)
  • 原文地址:https://www.cnblogs.com/strong-FE/p/12153228.html
Copyright © 2020-2023  润新知