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"); }
Compiling method: G C C-G graph_link.c graph_link main.c