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

 图是由有穷非空集合的顶点和顶点之间的边组成的集合,通常表示为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】,则存入这个结构中的情况为,如图:

原文地址:https://www.cnblogs.com/strong-FE/p/12153228.html