Sequence of variables for topological ordering
Qiao if clumsy (welcome reprint, but please specify Source: Http://blog.csdn.net/qiaoruozhuo)
Title Description:
Suppose there are n variables (1<=n<=26, the variable names are represented by a single lowercase letter), and M two-tuple (U,V), which indicates that the variable u is less than V, respectively. So what should all the variables look like from small to large?
For example, there are 4 variables a,b,c,d, and if A<b,c<b,d<c is known, the ordering of these 4 variables may be a<d<c<b. Although there may be other possibilities, you just need to find one of them.
Input:
The input is a string that contains n+n characters, which in turn represent N-relationships (1<=n<=100000), such as the sequence "ABCBDC", which represents a<b,c<b,d<c.
Output:
Gives a string that stores a sequence of variables that meet the requirements, for example, the string "ADCB" represents a<d<c<b.
Algorithm Analysis:
This is a typical topological ordering problem. First, a simple science, the so-called topological ordering, refers to a direction-free graph G all vertices into a linear sequence, so that any pair of vertices in the graph U and V, if <u,v>∈e (G), then u in a linear sequence in the presence of V. Typically, such a linear sequence is called a sequence that satisfies the topological order (Topoisicaiorder), referred to as a topological sequence.
We first enter the variable as a vertex into the graph data structure. The data structure of the representation graph has many, because the subject is sparse graph, should take the edge as the main object of study, so you can set the data structure as adjacency table or edge table set.
Let's look at the adjacency table data structure first:
typedef char Vertextype; Vertex types are custom-defined by the user
typedef int EDGETYPE; The weight type on the edge is custom-defined by the user
typedef struct edgenode{//Benzi node
Intadjvex; adjacency point field, which stores the subscript corresponding to the vertex
Edgetypeweight; For a non-grid diagram, it is not necessary to
Structedgenode *next; Chain field, pointing to the next adjacency point
} Edgenode;
typedef struct vertexnode{//Vertex table node
Vertextypedata; Vertex fields, storing vertex information
Intin; Number of storage vertex-in degrees
Edgenode*firstedge; Edge table Header pointer
} Vertexnode;
Since the variable name is represented by a single lowercase letter, we can set a storage vertex for an array of size 26, and since 26 letters do not necessarily appear, we set a global variable int book[maxm]= {0}; Used to mark whether a letter appears.
First, you create a diagram that reads the vertex and edge information. The code is as follows:
/*
Function Name: creategraph
function function: The vertex and edge information is read into the adjacency table of the representation graph
Input variable: Char *data: A string that stores N-relationships
Vertexnode *GL: Array of vertex tables
Output variable: An array of vertex tables representing graphs
return value: Int: number of vertices
*/
Intcreategraph (char *data, Vertexnode *GL)
{
int i, u, v;
int count = 0;//record vertex count
Edgenode *e;
for (i=0; i<maxm; i++)//initialization diagram
{
Gl[i].data = i + ' a ';
gl[i].in = 0;
Gl[i].firstedge = NULL;
Book[i] = 0;
}
for (i=0; data[i]!= '; i+=2)//Read two variables at a time
{
U = data[i]-' a '; The letters are converted to numbers, ' a ' corresponds to 0, ' B ' corresponds to 1, and so on
v = data[i+1]-' a ';
Book[u] = book[v] = 1;
E = (edgenode*) malloc (sizeof (Edgenode)); Inserting edge table nodes with head interpolation method
if (!e)
{
Puts ("Error");
Exit (1);
}
E->adjvex = v;
E->next = Gl[u].firstedge;
Gl[u].firstedge = e;
gl[v].in++;
}
for (i=0; i<maxm; i++)//COMPUTE vertex count
{
if (book[i]! = 0)
count++;
}
return count;
}
Topology sorting algorithm is very simple, only need to search for 0 of the arc tail vertex, and then its corresponding ARC head point in the degree minus 1, if the arc head point into the degree of 0, it is stored in the stack (or queue). The method of searching has two kinds of depth first and breadth first. The code is as follows:
/*
Function Name: Topologicalsort_dfs
function function: Topological ordering, using depth-first search to get topological sequence
Input variable: Char *topo: String used to store the topological sequence
Vertexnode *GL: Array of vertex tables
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort_dfs (char *topo,vertexnode *gl, int n)
{
Inti, U, V, top;
intcount = 0; Number of vertices used for statistical output
Edgenode*e;
INTSTACK[MAXM];
for (top=i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && gl[i].in = = 0)
{
stack[top++]= i;
}
}
while (Top > 0)//Use depth first search to get topological sequence
{
U= Stack[--top];
topo[count++]= U + ' a ';
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v= e->adjvex;
if (--gl[v].in = = 0)
Stack[top++]= v;
}
}
topo[count]= ' + ';
return (count = = N), or//if count is less than the number of vertices, indicates that there is a ring
}
/*
Function Name: TOPOLOGICALSORT_BFS
function function: Topological ordering, using breadth-first search to get topological sequence
Input variable: char*topo: The string used to store the topological sequence
Vertexnode *GL: Array of vertex tables
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort_bfs (char *topo,vertexnode *gl, int n)
{
Inti, U, V, front, rear;
Edgenode*e;
front= rear = 0;
for (i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && gl[i].in = = 0)
{
topo[rear++]= i + ' a ';
}
}
while (front < rear)//Use breadth-first search to get topological sequences
{
u= topo[front++]-' a ';
for (E=gl[u].firstedge; e!=null; e=e->next)//Reduce the adjacency point of U by 1 and put the vertex of the 0 into the stack
{
v= e->adjvex;
if (--gl[v].in = = 0)
Topo[rear++]= v + ' a ';
}
}
topo[rear]= ' + ';
return (rear = = n);//If Count is less than the number of vertices, it indicates that there is a ring
}
We can also use the edge table set to represent the graph, the data structure is as follows:
typedef struct edge{//edge set Array
Intu, V; ARC Tail and ARC head
Intnext; Point to the next edge of the same arc tail
Edgetypeweight; For a non-grid diagram, it is not necessary to
} edgelib;
To represent vertex information, we also need to set two arrays: int IN[MAXM], FIRST[MAXM]; Stores the entry and first edge information for the vertices, respectively.
The algorithm for topological ordering of Benzi is very similar to the adjacency table, which is the vertex and edge information of first reading in the graph, and then the topological sort. The code is as follows:
/*
Function Name: creategraph_2
function function: read vertex and edge information into the side table set of the presentation graph
Input variable: char*data: A string with n-Relationships stored
int in[]: Stores the entry information for vertices
int first[]: point to the first edge with the vertex as the end of the arc
Edgelib edge[]: Benzi set with edge information stored
Output variables: An array of Benzi sets that represent graphs
return value: Int: number of vertices
*/
int creategraph_2 (char *data, int in[], intfirst[], edgelib edge[])//Create a diagram
{
Inti, J;
intcount = 0;//Record vertex count
for (i=0; i<maxm; i++)//initialization diagram
{
first[i]=-1;
book[i]= 0;
in[i]= 0;
}
for (j=i=0; data[i]!= '; i+=2,j++)//Read two variables at a time
{
edge[j].u= Data[i]-' a '; The letters are converted to numbers, ' a ' corresponds to 0, ' B ' corresponds to 1, and so on
edge[j].v= data[i+1]-' a ';
book[edge[j].u]= BOOK[EDGE[J].V] = 1;
edge[j].next= FIRST[EDGE[J].U];
First[edge[j].u]= J;
in[edge[j].v]++;
}
for (i=0; i<maxm; i++)//COMPUTE vertex count
{
if (book[i]! = 0)
count++;
}
Returncount;
}
/*
Function Name: Topologicalsort
function function: Topological ordering, using breadth-first search to get topological sequence
Input variable: char*topo: The string used to store the topological sequence
Edgelib edge[]: Benzi set with edge information stored
int in[]: Stores the entry information for vertices
int first[]: point to the first edge with the vertex as the end of the arc
int N: Number of vertices
Output variable: The string used to store the topological sequence
return value: Int: Topological sort succeeded return true, False if ring is present
*/
int Topologicalsort (char *topo, edgelibedge[], int in[], int first[], int n)
{
Inti, U, front, rear;
front= rear = 0;
for (i=0; i<maxm; i++)//Enter the vertex of the 0 into the stack
{
if (book[i]! = 0 && In[i] = = 0)
{
topo[rear++]= i + ' a ';
}
}
while (front < rear)//Use breadth-first search to get topological sequences
{
u= topo[front++]-' a ';
for (i=first[u]; i!=-1; i=edge[i].next)
{
if (--in[edge[i].v] = = 0)
topo[rear++]= edge[i].v + ' a ';
}
}
topo[rear]= ' + ';
return (rear = = n);//If Count is less than the number of vertices, it indicates that there is a ring
}
Only the relevant functions are given here, and the complete test code should be viewed by a clumsy blog (Http://blog.csdn.net/qiaoruozhuo).
Analysis of variable sequence algorithm for topological sequencing