Algorithm Analysis of variable sequence in topological sorting
Variable Sequence in topological sorting
Clever if (Welcome to reprint, but please note the Source: http://blog.csdn.net/qiaoruozhuo)
Description:
Assume that there are n variables (1 <= n <= 26, the variable name is represented by a single lowercase letter), and m binary groups (u, v ), the u variable is smaller than v. So what should all variables look like from small to large?
For example, there are four variables a, B, c, d.
Input:
The input is a string containing N + N characters, indicating N relational relations (1 <= N <= 100000) in turn. For example, the sequence "abcbdc" indicates
Output:
A string that stores a sequence of variables that meet the requirements. For example, the string "adcb" indicates
Algorithm analysis:
This is a typical topologysorting problem. First, let's take a simple look. The so-called topological sorting refers to arranging all vertices in a directed acyclic graph G into a linear sequence so that any pair of vertices u and v in the graph. E (G), then u appears before v in linear sequence. Generally, such a linear sequence is called a sequence that satisfies the topological order.
We first input variables into the graph data structure as vertices. There are many data structures in the graph. Because this question corresponds to a sparse graph, we should take the edge as the main research object. Therefore, we can set the data structure as an adjacent table or edge table set.
Let's first look at the data structure of the adjacent table:
Typedef char VertexType; // The vertex type is customized by the user.
Typedef int EdgeType; // The weight type on the edge is customized by the user.
Typedef struct EdgeNode {// edge table Node
Intadjvex; // The subscripts corresponding to the vertex in the adjacent vertex field.
// EdgeTypeweight; // weight value, which is not required for non-network charts
StructEdgeNode * next; // link domain, pointing to the next adjacent point
} EdgeNode;
Typedef struct VertexNode {// vertex table Node
VertexTypedata; // vertex field that stores vertex Information
Intin; // store the number of vertex inputs
EdgeNode * firstEdge; // edge header pointer
} VertexNode;
Because the variable name is represented by a single lowercase letter, we can set an array with a size of 26 to store the vertex, And because 26 letters do not necessarily appear, therefore, we set a global variable int book [MAXM] = {0}; To Mark whether a letter appears.
First, create a graph and read the vertex and edge information. The Code is as follows:
/*
Function Name: CreateGraph
Function: Read vertices and edges in the adjacent table indicating the graph.
Input variable: char * data: string that stores N relational expressions
VertexNode * GL: vertex Table Array
Output variable: the vertex table array of the graph.
Return Value: int: Number of vertices
*/
IntCreateGraph (char * data, VertexNode * GL)
{
Int I, u, v;
Int count = 0; // Number of vertex records
EdgeNode * e;
For (I = 0; I
{
GL [I]. data = I + 'a ';
GL [I]. in = 0;
GL [I]. firstEdge = NULL;
Book [I] = 0;
}
For (I = 0; data [I]! = '\ 0'; I + = 2) // read two variables each time.
{
U = data [I]-'A'; // convert letters 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); // insert edge table nodes using the header Insertion 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
{
If (book [I]! = 0)
Count ++;
}
Return count;
}
The topological sorting algorithm is actually very simple. You only need to search for the arc tail vertex whose input degree is 0, and then subtract 1 from the arc header vertex, if the input of the arc header vertex is also 0, it is stored in the stack (or Queue. There are two search methods: depth first and breadth first. The Code is as follows:
/*
Function Name: TopoLogicalSort_DFS
Function: Performs topological sorting and obtains the topological sequence using deep priority search.
Input variable: char * topo: string used to store the topological Sequence
VertexNode * GL: vertex Table Array
Int n: Number of vertices
Output variable: string used to store the topological Sequence
Return Value: int: returns true if the topology is sorted successfully. If a ring exists, false is returned.
*/
Int TopoLogicalSort_DFS (char * topo, VertexNode * GL, int n)
{
Inti, u, v, top;
Intcount = 0; // used to count the number of output vertices
EdgeNode * e;
IntStack [MAXM];
For (top = I = 0; I
{
If (book [I]! = 0 & GL [I]. in = 0)
{
Stack [top ++] = I;
}
}
While (top> 0) // obtain the topological sequence with deep Priority Search
{
U = Stack [-- top];
Topo [count ++] = u + 'a ';
For (e = GL [u]. firstEdge; e! = NULL; e = e-> next) // reduce the inbound degree of the adjacent point of u by 1, and add the vertex with the inbound degree of 0 to the stack.
{
V = e-> adjvex;
If (-- GL [v]. in = 0)
Stack [top ++] = v;
}
}
Topo [count] = '\ 0 ';
Return (count = n); // If count is smaller than the number of vertices, a ring exists.
}
/*
Function Name: TopoLogicalSort_BFS
Function: Performs topological sorting and returns the topological sequence using the breadth-first search.
Input variable: char * topo: string used to store the topological Sequence
VertexNode * GL: vertex Table Array
Int n: Number of vertices
Output variable: string used to store the topological Sequence
Return Value: int: returns true if the topology is sorted successfully. If a ring exists, false is returned.
*/
Int TopoLogicalSort_BFS (char * topo, VertexNode * GL, int n)
{
Inti, u, v, front, rear;
EdgeNode * e;
Front = rear = 0;
For (I = 0; I
{
If (book [I]! = 0 & GL [I]. in = 0)
{
Topo [rear ++] = I + 'a ';
}
}
While (front <rear) // obtain the topological sequence using the breadth-first search
{
U = topo [front ++]-'A ';
For (e = GL [u]. firstEdge; e! = NULL; e = e-> next) // reduce the inbound degree of the adjacent point of u by 1, and add the vertex with the inbound degree of 0 to the stack.
{
V = e-> adjvex;
If (-- GL [v]. in = 0)
Topo [rear ++] = v + 'a ';
}
}
Topo [rear] = '\ 0 ';
Return (rear = n); // If count is smaller than the number of vertices, a ring exists.
}
We can also use edge table sets to represent graphs. The data structure is as follows:
Typedef struct Edge {// Number of Edge Sets
Intu, v; // arc tail and arc Header
Intnext; // point to the next edge at the end of the same arc
// EdgeTypeweight; // weight value, which is not required for non-network charts
} EdgeLib;
To represent vertex information, we also need to set two Arrays: int In [MAXM], first [MAXM]; // store the vertex's inbound and first edge information respectively.
The edge table Set Topology Sorting Algorithm is very similar to that of the adjacent table. It also reads vertex and edge information of the graph and performs topological sorting. The Code is as follows:
/*
Function Name: creategraph2
Function: Read vertex and edge information into the edge table set that represents the graph.
Input variable: char * data: string that stores N relational expressions
Int In []: stores vertex inbound Information
Int first []: point to the first edge ending with this vertex as the Arc
EdgeLib edge []: edge table set that stores edge information
Output variable: Number of edge table sets of a graph
Return Value: int: Number of vertices
*/
Int creategraph2 (char * data, int In [], intfirst [], EdgeLib edge []) // create a graph
{
Inti, j;
Intcount = 0; // record the number of vertices
For (I = 0; I
{
First [I] =-1;
Book [I] = 0;
In [I] = 0;
}
For (j = I = 0; data [I]! = '\ 0'; I + = 2, j ++) // read two variables each time.
{
Edge [j]. u = data [I]-'A'; // convert a letter to a number. '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
{
If (book [I]! = 0)
Count ++;
}
Returncount;
}
/*
Function Name: TopoLogicalSort
Function: Performs topological sorting and returns the topological sequence using the breadth-first search.
Input variable: char * topo: string used to store the topological Sequence
EdgeLib edge []: edge table set that stores edge information
Int In []: stores vertex inbound Information
Int first []: point to the first edge ending with this vertex as the Arc
Int n: Number of vertices
Output variable: string used to store the topological Sequence
Return Value: int: returns true if the topology is sorted successfully. If a ring exists, false is returned.
*/
Int TopoLogicalSort (char * topo, EdgeLibedge [], int In [], int first [], int n)
{
Inti, u, front, rear;
Front = rear = 0;
For (I = 0; I
{
If (book [I]! = 0 & In [I] = 0)
{
Topo [rear ++] = I + 'a ';
}
}
While (front <rear) // obtain the topological sequence using the breadth-first search
{
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] = '\ 0 ';
Return (rear = n); // If count is smaller than the number of vertices, a ring exists.
}
Here only the relevant functions are given, the complete test code can go to the blog (http://blog.csdn.net/qiaoruozhuo) to view.