c/c++ directed acycline graph

Keywords: C github

c/c++ directed acycline graph

Concept:

The lines between points in the graph are directional, and there are no rings in the graph. Graph implemented by adjacency table.

Nouns:

  • The degree of entry of a vertex: the number of lines to that vertex.
  • Extent of a vertex: The number of lines starting from this vertex.

Ideas for realization:

1. Calculate the entrance of each vertex and store it in the auxiliary array cnt

2. Find a set of vertices with entrance of 0.

3. Take a vertex from the set of vertices whose entrance is 0. This vertex is the first vertex (not unique).

4. Find the vertices with three vertices as the starting point, then subtract the entries of these vertices by one, and find that if the entries are zero, update the auxiliary array cnt

5, Repeat 2-4

Difficulties:

The role of auxiliary array cnt:

  • Initially, the entry of each vertex is stored.
  • After finding the vertex with zero entrance, enter the stack; the element that goes out of the stack is the vertex that is found. After finding the vertex with zero entrance, continue to enter the stack, and then go out of the stack.

The use of auxiliary array cnt, it is recommended to use gdb, debug several times, you can understand.

Figure 1 below:

Figure 1

graph_link.h

#ifndef __graph_link__
#define __graph_link__

#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <memory.h>

#define default_vertex_size 10
#define T char

//Edge structure
typedef struct Edge{
  //Subscription of vertex
  int idx;
  //A pointer to the next side
  struct Edge* link;
}Edge;

//The structure of vertices
typedef struct Vertex{
  //The Value of Vertex
  T data;
  //edge
  Edge* adj;
}Vertex;

//The Structure of Graphs
typedef struct GraphLink{
  int MaxVertices;
  int NumVertices;
  int NumEdges;

  Vertex* nodeTable;
}GraphLink;

//Initialization diagram
void init_graph_link(GraphLink* g);
//Display chart
void show_graph_link(GraphLink* g);
//Insert Vertex
void insert_vertex(GraphLink* g, T v);
//Insert edge and tail
void insert_edge_tail(GraphLink* g, T v1, T v2);
//Insert edge insert
void insert_edge_head(GraphLink* g, T v1, T v2);
//Gets the first postordinal vertex of the specified vertex
int get_first_neighbor(GraphLink* g, T v);
//Gets the first postordinal vertex of the street vertex v2 of the specified vertex v1
int get_next_neighbor(GraphLink* g, T v1, T v2);

//Topological Sorting
void topo_sort(GraphLink* g);

#endif

graph_link.c

#include "graph_link.h"

//Initialization diagram
void init_graph_link(GraphLink* g){
  g->MaxVertices = default_vertex_size;
  g->NumVertices = g->NumEdges = 0;

  g->nodeTable = (Vertex*)malloc(sizeof(Vertex) * g->MaxVertices);
  assert(NULL != g->nodeTable);
  for(int i = 0; i < g->MaxVertices; ++i){
    g->nodeTable[i].adj = NULL;
  }
}

//Display chart
void show_graph_link(GraphLink* g){
  if(NULL == g)return;
  for(int i = 0; i < g->NumVertices; ++i){
    printf("%d %c->", i, g->nodeTable[i].data);
    Edge* p = g->nodeTable[i].adj;
    while(NULL != p){
      printf("%d->", p->idx);
      p = p->link;
    }
    printf(" NULL\n");
  }
}

//Insert Vertex
void insert_vertex(GraphLink* g, T v){
  if(g->NumVertices >= g->MaxVertices)return;
  g->nodeTable[g->NumVertices++].data = v;
}

//Find the index of vertex
int getVertexIndex(GraphLink* g, T v){
  for(int i = 0; i < g->NumVertices; ++i){
    if(v == g->nodeTable[i].data)return i;
  }
  return -1;
}

//Create edges
void buyEdge(Edge** e, int idx){
  Edge* p = (Edge*)malloc(sizeof(Edge));
  p->idx = idx;
  p->link = NULL;
  if(NULL == *e){
    *e = p;
  }
  else{
    Edge* tmp = *e;
    while(tmp->link != NULL){
      tmp = tmp->link;
    }
    tmp->link = p;
  }
}
//Insert edge (tail insert)
void insert_edge_tail(GraphLink* g, T v1, T v2){
  int p1 = getVertexIndex(g, v1);
  int p2 = getVertexIndex(g, v2);

  if(p1 == -1 || p2 == -1)return;
  
  buyEdge(&(g->nodeTable[p1].adj), p2);
  g->NumEdges++;
  buyEdge(&(g->nodeTable[p2].adj), p1);
  g->NumEdges++;

}
//Insert Edge (Head Insert)
void insert_edge_head(GraphLink* g, T v1, T v2){
  int p1 = getVertexIndex(g, v1);
  int p2 = getVertexIndex(g, v2);

  if(p1 == -1 || p2 == -1)return;

  Edge* p = (Edge*)malloc(sizeof(Edge));
  p->idx = p2;
  p->link = g->nodeTable[p1].adj;
  g->nodeTable[p1].adj = p;

  /*  
  p = (Edge*)malloc(sizeof(Edge));
  p->idx = p1;
  p->link = g->nodeTable[p2].adj;
  g->nodeTable[p2].adj = p;  
  */
}

//Gets the first postordinal vertex of the specified vertex
int get_first_neighbor(GraphLink* g, T v){
  int i = getVertexIndex(g, v);
  if (-1 == i)return -1;
  Edge* p = g->nodeTable[i].adj;
  if(NULL != p)
    return p->idx;
  else
    return -1;
}

//Gets the first postordinal vertex of the street vertex v2 of the specified vertex v1
int get_next_neighbor(GraphLink* g, T ve1, T ve2){
  int v1 = getVertexIndex(g, ve1);
  int v2 = getVertexIndex(g, ve2);
  if(v1 == -1 || v2 == -1)return -1;

  Edge* t = g->nodeTable[v1].adj;
  while(t != NULL && t->idx != v2){
    t = t->link;
  }
  if(NULL != t && t->link != NULL){
    return t->link->idx;
  }
  return -1;
}

//Topological Sorting
void topo_sort(GraphLink* g){
  int n = g->NumVertices;

  //Represents the degree of entry of each vertex, initialized to 0
  int* cnt = (int*)malloc(sizeof(int) * n);
  assert(NULL != cnt);
  for(int i = 0; i < n; ++i){
    cnt[i] = 0;
  }

  Edge* p;
  //Calculate the entrance of each vertex
  for(int i = 0; i < n; ++i){
    p = g->nodeTable[i].adj;
    while(p != NULL){
      cnt[p->idx]++;
      p = p->link;
    }
  }

  int top = -1;
  for(int i = 0; i < n; ++i){
    if(cnt[i] == 0){
      //Vertex Stacking with Degree 0 (Simulated Stacking)
      cnt[i] = top; //push
      top = i;
    }
  }

  int v,w;
  for(int i = 0; i < n; ++i){
    if(top == -1)return;//Circuit Existence

    v = top;         //Simulate the stack
    top = cnt[top];
    printf("%c->", g->nodeTable[v].data);
    w = get_first_neighbor(g, g->nodeTable[v].data);
    while(-1 != w){
      if(--cnt[w] == 0){
        //Vertex Stacking with Degree 0 (Simulated Stacking)
    cnt[w] = top;
    top = w;
      }
      w = get_next_neighbor(g,g->nodeTable[v].data,g->nodeTable[w].data);
    }
  }
  free(cnt);
}

graph_linkmain.c

#include "graph_link.h"

int main(){
  GraphLink gl;
  //Initialization diagram
  init_graph_link(&gl);
  //Insert Node
  insert_vertex(&gl, 'A');
  insert_vertex(&gl, 'B');
  insert_vertex(&gl, 'C');
  insert_vertex(&gl, 'D');
  insert_vertex(&gl, 'E');
  insert_vertex(&gl, 'F');

  //Insert Edge (Head Insert)
  insert_edge_head(&gl, 'A', 'B');
  insert_edge_head(&gl, 'A', 'C');
  insert_edge_head(&gl, 'A', 'D');
  insert_edge_head(&gl, 'C', 'B');
  insert_edge_head(&gl, 'C', 'E');
  insert_edge_head(&gl, 'D', 'E');
  insert_edge_head(&gl, 'F', 'D');
  insert_edge_head(&gl, 'F', 'E');

  //Display chart
  show_graph_link(&gl);

  //Topological Sorting
  topo_sort(&gl);

  printf("\n");
}

Complete code

Compiling method: G C C-G graph_link.c graph_link main.c

Posted by OilSheikh on Mon, 04 Feb 2019 04:00:16 -0800