Data structure and algorithm - recognize graph structure, graph representation, graph structure implementation, graph traversal

Posted by siefkencp on Wed, 12 Jan 2022 19:40:26 +0100

catalogue

1, Initial graph structure

1. What is a graph

2. Features of the drawing

  3. Terminology of Graphs

        (1). vertex

        (2). edge

        (3). Adjacent vertex

        (4). degree

        (5). route

        (6). Undirected graph

        (7). Directed graph

        (8). Weighted graph and weighted graph

II Representation of Graphs

  1. vertex representation

  2. adjacency matrix

  3. Adjacency table

III Implementation of graph structure

  1. Package diagram structure

  2. How to add vertices

  3. How to add edges

  4.toString() method

4, Traversal of Graphs

  1. Traversal mode

        (1). Ergodic idea of graph

        (2). Notes on traversal

        (3). The idea of two algorithms

  2. Breadth first search

        (1). Idea of breadth first search algorithm

        (2). Implementation of breadth first search

  3. Depth first search

        (1). Idea of depth first search

        (2). Implementation of depth first search algorithm

1, Initial graph structure

1. What is a graph

Graph is a kind of data structure similar to tree. In fact, in the mathematical concept, tree is a kind of graph.

Trees can be used to simulate many real data structures, such as genealogy, company organizational structure and so on. At the same time, the subway map can be used to simulate the map:

The relationship between the above nodes (actually called vertex vertex in the graph) cannot be represented by a tree (not even a few fork trees). At this time, you can use a graph to simulate them.

2. Features of the drawing

A set of vertices: usually V (Vertex) represents the set of vertices

A set of edges: usually E (Edge) represents the set of edges

An edge is a line between vertices

Edges can be directed or undirected. (for example, A --- B usually means undirected. A -- > b usually means directed)

  3. Terminology of Graphs

The following figure is an abstract diagram:

        (1). vertex

A vertex represents a node in a graph.

For example, a station in a subway station, a village in multiple villages, a host in the Internet, and people in interpersonal relationships.

        (2). edge

Edges represent vertices and lines between vertices.

For example, the direct connection between two stations in the subway station is one side.

Note: the edges here are not called paths. Paths have other concepts

In the above figure: 0 - 1 has an edge, 1 - 2 has an edge, 0 - 2 has no edge

        (3). Adjacent vertex

Vertices connected by one edge are called adjacent vertices.

For example, 0 - 1 is adjacent and 0 - 3 is adjacent 0 - 2 are not adjacent

        (4). degree

The degree of a vertex is the number of adjacent vertices.

For example, vertex 0 is connected with two other vertices, and the degree of vertex 0 is 2

For example, vertex 1 is connected to the other four vertices, and the degree of vertex 1 is 4

        (5). route

The path is vertex V1, V2, A continuous sequence of VN, such as 0 1 5 9 in the figure above, is a path

   1. Simple path: a simple path requires no duplicate vertices For example, 0 1 5 9 is a simple path

   2. Loop: the same path between the first vertex and the last vertex is called a loop For example, 0 1 5 6 3 0

        (6). Undirected graph

The graph above is an undirected graph because all edges have no direction.

For example, if there is a change between 0 and 1, it means that this edge can guarantee 0 - > 1 and 1 - > 0

        (7). Directed graph

The edges in a directed graph are directional.

For example, 0 - > 1 cannot guarantee 1 - > 0, which should be determined according to the direction

        (8). Weighted graph and weighted graph

        1. Unauthorized graph

The graph above is a weight free graph (edges do not carry weights)

The edges in our figure above are meaningless. We can't close the 0 - 1 edge, which is farther or longer than the 4 - 9 edge

        2. Weighted graph

The weighted graph indicates that the edges have a certain weight.

The weight here can be any desired data, such as distance or time spent or ticket price

The following figure is a directed and weighted diagram:

II Representation of Graphs

A graph contains many vertices, as well as vertices and lines (edges) between vertices. These two are very important graph information.

  1. vertex representation

The representation of vertices is relatively simple. The vertices above are abstracted into 1 2 3 4, or A B C D. These A, B, C, D can be stored using an array (storing all vertices). Of course, a, B, C and D may also represent data with other meanings (such as the name of the subway station). At this time, another array can be created to store other corresponding data

  2. adjacency matrix

The adjacency matrix associates each node with an integer that is used as the subscript value of the array. Use a two-dimensional array to represent the connection between vertices

In the two-dimensional array, 0 means no connection and 1 means there is a connection.

Through the two-dimensional array, you can quickly find A vertex and which vertices have connections. (for example, vertex A, you only need to traverse the first row)

In addition, a - A and B - B (that is, the line from the vertex to itself) are usually represented by 0

The problem of adjacency matrix:

If it is an undirected graph, the two-dimensional array displayed by the adjacency matrix is actually a symmetric graph. That is, when a - > D is 1, the symmetrical position D - > 1 must also be 1.

Another serious problem of adjacency matrix is that if the graph is a sparse graph, there will be a large number of zeros in the matrix, which means that computer storage space is wasted to represent non-existent edges. Even if there is only one edge, you must traverse a row to find this edge, which also wastes a lot of time

  3. Adjacency table

The adjacency list consists of each vertex in the graph and a list of vertices adjacent to the vertex. This list can be stored in many ways: array / linked list / Dictionary (hash table), etc

To represent the vertices (edges) associated with vertex A, and A and B/C/D have edges, you can find the corresponding array / linked list / dictionary through A, and then take out the contents.

Adjacency table problem:

The adjacency table is relatively simple to calculate the "out degree" (out degree: point to the number of others, in degree: point to your own number). The adjacency table is troublesome if it is necessary to calculate the "penetration" of a directed graph. An "inverse adjacency table" must be constructed to effectively calculate the "penetration".

III Implementation of graph structure

  1. Package diagram structure

    //Package diagram structure
    function Graph(){
        //Attributes: vertex (array) / edge (Dictionary)
        this.vertexes = []  //vertex
        this.edges = new Dictionay()    //edge

    }

Create the constructor of Graph and define two properties:

Vertices: used to store all vertices. We said to use an array to save

adjList: adj is the abbreviation of adj, which means adjacency adjList is used to store all edges in the form of adjacency table

  2. How to add vertices

Add some vertices to the graph

    //1. Method of adding vertices
    Graph.prototype.addVertex = function(v){
        this.vertexes.push(v)
        this.edges.set(v,[])
    }

Put the added vertex into the array. In addition, create an array [] for the vertex, which is used to store all the edges connected by the vertex

  3. How to add edges

    //2. Method of adding edges
    Graph.prototype.addEdge = function(v1,v2){
        this.edges.get(v1).push(v2)
        this.edges.get(v2).push(v1)
    }

Adding an edge requires two vertices to be passed in, because the edge is an edge between two vertices, and the edge cannot exist alone

Take out the corresponding array according to vertex v and add w to its array

Take out the corresponding array according to vertex w and add v to its array

Here is an undirected graph, so edges can be bidirectional

Test code:

    //Test code
    //1. Create chart structure
    var g = new Graph()
    //2. Add vertex
    var myVertexes = ['A','B','C','D','E','F','G','H','I']
    for(var i=0; i<myVertexes.length; i++){
        g.addVertex(myVertexes[i])
    }
    //3. Add edge
    g.addEdge('A','B')
    g.addEdge('A','C')
    g.addEdge('A','D')
    g.addEdge('C','D')
    g.addEdge('C','G')
    g.addEdge('D','G')
    g.addEdge('D','H')
    g.addEdge('B','E')
    g.addEdge('B','F')
    g.addEdge('E','I')
    //test
    alert(g)

  4.toString() method

    //Implement toString method
    Graph.prototype.toString = function(){
        //1. Define the string and save the final result
        var resultString = ''

        //2. Traverse all nodes and edges corresponding to vertices
        for(var i =0; i<this.vertexes.length; i++){
            resultString += this.vertexes[i] + "->"
            var vEdges = this.edges.get(this.vertexes[i])
            for(var j=0; j<vEdges.length; j++){
                resultString += vEdges[j] + ' '
            }
            resultString += '\n'
        }
        return resultString
    }

4, Traversal of Graphs

  1. Traversal mode

        (1). Ergodic idea of graph

The idea of graph traversal algorithm is to visit each node visited for the first time, and track which vertices have not been accessed. There are two algorithms that can traverse the graph: breadth first search (BFS) and depth first search (DFS)

Both traversal algorithms need to specify the first vertex to be accessed.

        (2). Notes on traversal

For each connected vertex that has not been accessed, mark it as discovered and add it to the list of vertices to be accessed. In order to ensure the efficiency of the algorithm, each vertex can be accessed at most twice.

        (3). The idea of two algorithms

BFS: Based on the queue, the vertices entering the queue are explored first

DFS: Based on the stack, by storing vertices in the stack, vertices are explored along the path, and new adjacent vertices are accessed

In order to record whether vertices have been accessed, we use three colors to reflect their state: (or two colors can also be used)

White: indicates that the vertex has not been accessed

Gray: indicates that the vertex has been visited but not explored

Black: indicates that the vertex has been visited and fully explored

Initialize color code:

    //Initialization status color
    Graph.prototype.initializeColor = function(){
        var colors = []
        for(var i=0; i<this.vertexes.length; i++){
            colors[this.vertexes[i]] = 'white'
        }
        return colors
    }

  2. Breadth first search

        (1). Idea of breadth first search algorithm

The breadth first algorithm will traverse the graph from the specified first vertex and access all its adjacent points first, just like accessing one layer of the graph at a time. In other words, it is to access vertices from width to depth.

        (2). Implementation of breadth first search

    //Achieve breadth first search
    Graph.prototype.bfs = function (initV, handler) {
        //1. Initialize color
        var colors = this.initializeColor()

        //2. Create queue
        var queue = new Queue()

        //3. Add vertices to the queue
        queue.enqueue(initV)

        //4. Loop to fetch elements from the queue
        while (!queue.isEmpty()) {
            //4.1. Take a vertex from the queue
            var v = queue.dequeue()

            //4.2. Gets another vertex connected to the vertex
            var vList = this.edges.get(v)

            //4.3. Set the color of v to gray
            colors[v] = 'gray'

            //4.4 traverse all vertices and join the queue
            for (var i = 0; i < vList.length; i++) {
                var e = vList[i]
                if (colors[e] == 'white') {
                    colors[e] = 'gray'
                    queue.enqueue(e)
                }
            }

            //4.5 access vertex
            handler(v)

            //4.6. Set vertices to black
            colors[v] = 'black'
        }
    }

Test code:

// Call breadth first algorithm
var result = ""
graph.bfs(graph.vertexes[0], function (v) {
    result += v + " "
})
alert(result) // A B C D E F G H I 

  3. Depth first search

        (1). Idea of depth first search

The depth first search algorithm will traverse the graph from the first specified vertex, and follow the path until the path is finally accessed

Then go back and explore a path.

 

        (2). Implementation of depth first search algorithm

The breadth first search algorithm uses queues, which can be completed by stack or recursion. In order to facilitate code writing, recursion is used (recursion is essentially the call of function stack)

    //Depth first search (DFS)
    Graph.prototype.dfs = function(initV,handler){
        //1. Initialize color
        var colors = this.initializeColor()

        //2. Recursive access from a vertex in turn
        this.dfsVisit(initV,colors,handler)
    }
    Graph.prototype.dfsVisit = function(v,colors,handler){
        //1. Set the color to gray
        colors[v] = 'gray'

        //2. Processing v node
        handler(v)

        //3. Access v connected vertices
        var vlist = this.edges.get(v)
        for(var i=0; i < vlist.length; i++){
            var e = vlist[i]
            if(colors[e] == 'white'){
                this.dfsVisit(e,colors,handler)
            }
        }

        //4. Set v to black
        colors[v]='black'
    }

Test code:

    //Call depth first algorithm
    result = ''
    g.dfs(g.vertexes[0],function(v){
        result += v + ' '
    })
    alert(result)

Recursive procedure:

 

Topics: Javascript Front-end Algorithm data structure