A defined topological sort is a sort of vertex of a directed acyclic graph (Directed acyclic graph abbreviation dag),
It enables a path from vertex A to vertex b if one exists, and B appears behind a in the sort.
Two prerequisites to be able to perform a topological sort diagram There are two prerequisites: there is a direction, no ring, that is, a direction-free graph.
Three partial order full-sequence connectivity graph: At least one edge exists between any two points
Partial order: Non-connected graph (with a direction-free graph to satisfy the partial order relationship)
Full order: Single connected graph
Four-result uniqueness for a forward-loop graph that satisfies only partial-order relationships, because the relationship between two points is indeterminate, the result of ordering is not unique.
There is a direction-free graph that satisfies the whole order relationship, and there is a forward edge between the two points, so the ordering result is unique.
Five-in-order ordering each step of the method always outputs the vertices that are not current (that is, 0), and outputs the "topological order".
The abstract algorithm can be described as:
Nonprefirsttopsort (G) {//Priority output of pre-trend vertices
While (a vertex with a degree of 0 in G) do{
Select a vertex v with an entry degree of 0 from G and output it;
Delete V and all its out edges from G;
}
if (number of vertices output <| V (G) |) If this condition is not true, all vertices are output and the sorting is successful.
Error ("There is a forward loop in G, sort failed!") ");
}
Attention:
An unprecedented vertex-first topological sorting algorithm, under the specific storage structure, can save the current degree of each vertex in order to examine the degree of each vertex's entry.
To avoid scanning the entire storage space each time a vertex of 0 is selected, you can set up a stack or queue to hold all vertices that have zero in degrees:
Before starting the sorting, scan the corresponding storage space and put the zero-in vertices into the stack (team). Each time you select a vertex of 0, you only need to make a stack (team) operation.
Six-out order each step of the method is to output a vertex with no successor (that is, 0), outputting the inverse topological order.
The abstract description of the algorithm is:
Nonsuccfirsttopsort (G) {//Priority output no successor vertices
While (a vertex with a degree of 0 in G) do {
Select a 0 vertex v from G and output V;
Delete all the sides of V and V from G
}
if (number of vertices output <| V (G) |)
Error ("There is a forward loop in G, sort failed!") ;
}
Seven depth priority when DFS search is completed from a vertex V, all successors to V must have been accessed (imagine that they have been deleted),
The V at this point is equivalent to a no successor vertex, so the inverse topological sequence of the DAG can be obtained before the DFS algorithm returns to output vertex v.
The vertex of the first output must be a vertex with no successor (out of 0), which should be the last vertex of the topological sequence.
If you want to get not the inverse topological sequence, you can add t to save the vertices of the output. If T is a stack and the T is initialized at the beginning of the dfstraverse algorithm,
The abstract algorithm using DFS to find topological sequences can be described as:
void Dfstopsort (g,i,t) {
Call this algorithm in Distraverse, I is the starting point of the search, T is the stack
Int J;
Visited[i]=true;//Access I
For (All I adjacency point j)//IE <i,j>∈e (G)
if (!visited[j])
Dfstopsort (g,j,t);
The above statement is exactly like the DFS algorithm
Push (&t,i);//search completed from I, Output I
}
Eight code only realized the degree, the other two kind of almost, did not write.
GraphList.h (the code based on this article modifies the algorithm and the data structure base 8:c++ implementation of the graph-adjacency table storage)
#include <iostream> #include <cstdio> #include <stack> #include <queue>using namespace std;// Edge struct edge{int vname;int weight;//weight struct edge* next;};/ /vertex (list header) struct vertex{int vname;int in;//int out;//perceive struct edge* next;};/ /Graph class graphlist{public:~graphlist (); void Creategraph (); void Printgraph (); bool Topsortindegree (); bool Topsortoutdegree ();p rivate://1. Input fixed-point number void Inputvertexcount ();//2. Generates a fixed-point array void Makevertexarray ();//3. Input number of sides void Inputedgecount ();//4. The starting point of the input edge is void inputedgeinfo ();//5. Add edge nodes to the corresponding list of void addedgetolist (int vfrom, int weight, int vTo);p rivate:int m_vcount;int M_ecount; Vertex* M_vvertex;}; Graphlist::~graphlist () {for (int i = 0; i < M_vcount; ++i) {edge* tmp = M_vvertex[i].next; edge* edge = Null;while (tmp) {edge = Tmp;tmp = Tmp->next;delete Edge;edge = NULL;}} Delete[] M_vvertex;} void Graphlist::inputvertexcount () {cout << "Please input count of vertex:"; cin >> M_vcount;} void Graphlist::makevertexarray () {M_vvertex = new Vertex[m_vcount];//Initialize for (int i = 0; i < M_vcount; ++i) {m_vvertex[i].vname = I;m_vvertex[i].next = null;m_vvertex[i].in = 0;m_vvertex[i].out = 0;}} void Graphlist::inputedgecount () {cout << "please input count of Edge:"; cin >> M_ecount;} void Graphlist::inputedgeinfo () {cout << "please input edge information:" << endl;for (int i = 0; i < M_ecount; ++i) {cout << "the Edge" << I << ":" << endl;//start int from = 0;cout << "from:"; Cin >> from;//weight int weight = 0;cout << "Weight:"; cin >> weight;//end int to = 0;cout << "to:"; Cin >> to ; cout << endl;addedgetolist (from, weight, to);}} void graphlist::addedgetolist (int vfrom, int weight, int vTo) {edge* edge = new Edge (); edge->vname = Vto;edge->weight = Weight;edge->next = NULL; edge* tmp = M_VVERTEX[VFROM].NEXT;IF (TMP) {while (tmp->next) {tmp = Tmp->next;} Tmp->next = Edge;} Else{m_vvertex[vfrom].next = Edge;} ++m_vvertex[vto].in;//End-of-entry plus 1++m_vvertex[vfrom].out;//beginning perceive plus 1}void graphlist::p rintgraph () {for (int i = 0; i < M_vcount; ++i) {edge* tmp = M_vvertex[i].ne Xt;cout << "list:" << m_vvertex[i].vname << "(In:" << m_vvertex[i].in << ")" << " "while (TMP) {cout <<" (Weight: "<< tmp->weight <<") "cout << tmp->vname <<", "; TMP = Tmp->next;} cout << "NULL" << Endl;}} BOOL Graphlist::topsortindegree () {stack<vertex*> vertexstack;queue<vertex*> vertexQueue;int* degree = New int[m_vcount];//declares a temporary variable that holds the value of the entry to be manipulated to avoid affecting the data in the original node//1 statistics into the 0 points for (int i = 0; i < M_vcount; ++i) {Degree[i] = M_vverte X[i].in;if (!degree[i]) {Vertexstack.push (&m_vvertex[i]);}} int count = 0;while (!vertexstack.empty ()) {//Save the 0 point vertex* tmp = Vertexstack.top (); Vertexstack.pop (); Vertexqueue.push (TMP); ++count;//2 Deletes the node and all its out edges (that is, the adjacent point in degrees minus 1) edge* edge = Tmp->next;while (edge) {vertex* Vertex = &m_vvertex[edge->vname];--degree[edge->vname];if (!degrEe[edge->vname]) {Vertexstack.push (vertex);} Edge = Edge->next;}} Determine if there is a ring if (count < M_vcount) {return false;} Output sort result while (!vertexqueue.empty ()) {vertex* tmp = Vertexqueue.front (); Vertexqueue.pop (); cout << Tmp->vname << "";} cout << endl;delete[] Degree;return true;} Process Control//*************************** void Graphlist::creategraph () {inputvertexcount (); Makevertexarray (); Inputedgecount (); Inputedgeinfo ();}
Main.cpp
Test for Graphlist#include "GraphList.h" #include <cstdlib>int main () {graphlist graph;graph.creategraph (); Graph.printgraph (); Graph.topsort (); System ("pause"); return 0;}
If there is a picture as follows: (just the diagram of the previous two sections)
Results:
Algorithm and data Structure Foundation 10:c++ implementation--topological sort