/*
Name:
Copyright:
Author:
Date:17-11-14 21:02
Description: sequence of variables for topological sequencing
If there are n variables (1<=n<=26, the variable names are represented in a single lowercase letter). There are also M two-tuple (u,v), which indicate that the variable u is less than v.
So what should all the variables look like from small to large?
For example, There are 4 variables a,b,c,d, if a<b,c<b,d<c, then 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
Enter as a string of data, including N+n Characters. Represents 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.
*/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAXM 26//maximum Number of variables (vertices)
#define MAXN 100000//maximum Relationship Quantity
typedef char vertextype; Vertex types are defined by the user themselves
typedef int edgetype; The weight type on the edge is defined by the user himself
typedef struct EDGENODE{//BENZI Node
int adjvex; Adjacency Point field, which stores the corresponding subscript for the vertex
// Edgetype weight; The weight Value. For non-network diagram can not need
struct Edgenode *next; Chain field, pointing to the next adjacency point
} edgenode;
typedef struct VERTEXNODE{//VERTEX Table node
Vertextype data; Vertex fields, storing vertex information
int in; Number of storage vertex-in degrees
Edgenode *firstedge; Edge table Header pointer
} vertexnode;
typedef struct EDGE{//EDGE Set array
int u, v; ARC Tail and ARC head
int next; Point to the next edge of the same arc tail
// Edgetype weight; For a non-network diagram, no need to
} edgelib;
int book[maxm] = {0}; Mark if a letter appears
int istoposeq (char *data, Char *topo);//based on the relational list data, infer whether the topo string is a topological sequence
int creategraph (char *data, vertexnode *gl);//create a diagram
void Printgraph (vertexnode *gl);//output diagram
int Topologicalsort_dfs (char *topo, vertexnode *gl, int n),//topological sort, get topological sequence, return False if ring is present
int Topologicalsort_bfs (char *topo, vertexnode *gl, int n);//topological sort, gets the topological sequence. return False if there is a ring
int creategraph_2 (char *data, int in[], int first[], edgelib edge[]);//create a diagram
void printgraph_2 (int first[], edgelib edge[]);//output diagram
int Topologicalsort (char *topo, edgelib edge[], int in[], int first[], int n);//topological sort. Gets the topological sequence, returns False if the ring exists, uses the queue to store the topological sequence
int main ()
{
int i, n;
Vertexnode gl[maxm];
Char topo[maxm+1];
Char data[maxn+maxn+1];
int in[maxm], first[maxm]; Storing vertex information
Edgelib edge[maxn]; Storage Edge Information
Gets (data);
n = creategraph_2 (data, in, first, edge);//create a diagram
printgraph_2 (first, edge);//output Diagram
If (topologicalsort (topo, edge, in, first, n))//using topological sequencing to construct topological sequences
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
If (istoposeq (data, topo))//based on the relational list Data. Infer if the topo string is a topological sequence
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
Gets (data);
n = creategraph (data, GL);//create a diagram
Printgraph (GL);//output diagram
If (istoposeq (data, topo))//based on the relational list data, infer whether the topo string is a topological sequence
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
If (topologicalsort_bfs (topo, GL, n))//using topological sequencing to construct topological sequences
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
Gets (data);
n = creategraph (data, GL);//create a diagram
Printgraph (GL);//output diagram
If (topologicalsort_dfs (topo, GL, n))//using topological sequencing to construct topological sequences
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
If (istoposeq (data, topo))//based on the relational list data, infer whether the topo string is a topological sequence
Puts (topo);
Else
Puts ("there is no sequence to satisfy the condition");
Return 0;
}
/*
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
*/
int creategraph (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 ' corresponding to 1. And so on
v = data[i+1]-' a ';
book[u] = book[v] = 1;
E = (edgenode*) malloc (sizeof (edgenode)); Insert the Edge table node with the 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;
}
void Printgraph (vertexnode *gl)//output diagram
{
int u, v;
Edgenode *e;
For (u=0; u<maxm; U++)
{
printf ("g[%d] =%c:", u, gl[u].data);
For (e=gl[u].firstedge; e!=null; e=e->next)//reduce the adjacency point of U by 1. And put the vertex into the stack with a degree of 0.
{
v = e->adjvex;
printf ("<%c,%c>,", gl[u].data, gl[v].data);
}
printf ("\ n");
}
printf ("\ n");
}
/*
function Name: Topologicalsort_dfs
function function: topological sort, 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)
{
int i, u, v, top;
int count = 0; Number of vertices used for statistical output
Edgenode *e;
int stack[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)//adopt 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);//assuming count is less than the number of vertices, indicating 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: 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: topology sort successfully returned True. return False if there is a ring
*/
int Topologicalsort_bfs (char *topo, vertexnode *gl, int N)
{
int i, 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)//using 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 into the stack with a degree of 0.
{
v = e->adjvex;
if (--gl[v].in = = 0)
topo[rear++] = v + ' a ';
}
}
topo[rear] = ' + ';
return (rear = = N);//assuming count is less than the number of vertices, indicating that there is a ring
}
/*
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 that stores n-relationships
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[], int first[], edgelib edge[])//create a diagram
{
int i, j;
int count = 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 ' corresponding to 0, ' B ' corresponding to 1, etc.
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++;
}
Return count;
}
void printgraph_2 (int first[], edgelib edge[])//output diagram
{
int i, j;
For (i=0; i<maxm; I++)
{
printf ("g[%d] =%c:", i, i+ ' a ');
j = first[i]; Point to the first side of I
While (j! =-1)
{
printf ("<%c,%c>,", edge[j].u+ ' a ', edge[j].v+ ' a ');
j = edge[j].next; Point to next Edge
}
printf ("\ n");
}
printf ("\ n");
}
/*
function Name: Topologicalsort
function Function: topology Sort. Acquiring topological sequences with Breadth-first search
Input variable: char *topo: 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: topology sort successfully returned True. return False if there is a ring
*/
int Topologicalsort (char *topo, edgelib edge[], int in[], int first[], int N)
{
int i, 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)//using 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);//assume count is less than the number of Vertices. Indicates that there is a ring
}
int istoposeq (char *data, char *topo)//based on relational list Data. Infer if the topo string is a topological sequence
{
int pos[maxm] = {0};
int i;
For (i=0; topo[i]!= '; i++)//read variable subscript
pos[topo[i]-' a '] = i;
For (i=0; data[i]!= '; i+=2)//read Two variables at a time
{
If (pos[data[i]-' a '] > pos[data[i+1]-' a ')
Return false;
}
Return true;
}
Variable sequence code of topological ordering