Data structure and algorithm--a topological sort of a direction-free graph C + + implementation

Source: Internet
Author: User

Introduction to Topology Ordering:topological ordering is a sort of vertex with a direction-free graph , so that if there is a path from VI to VJ, then VI is in the front of the VJ in the order. if the diagram contains loops, then topological sequencing is not possible. In addition, topological ordering does not have to be unique, and any reasonable sort can be.

for the above loop-free diagram: V1,V2,V5,V4,V3,V7,V6 and v1,v2,v5,v4,v7,v3,v6 are reasonable topological sorts.
A simple idea for topological sequencing:1, first find any one without the edge of the vertex2. Then show the point, and delete it and all of its adjacent edges. 3, then, the other parts of the diagram to do the same treatment.
Graphs are stored using adjacency table notation:Reference Blog: Data structure and algorithm--C + + implementation of adjacency table notation class of graphs



The left-hand array is now useful to hold information about each vertex, and the data structure for each element in the array is:
The data structure that holds each vertex information struct graphnode{    int vertex;//The current vertex's designator    int indegree;//The current vertex's in    int topnum;// Sequential label of the topology sort of the current vertex};

interface of the class of the adjacency notation of the graph:
/********************************************************  class name: adjacency table Diagram **************************************** /class graph{    private:        int edge_num;//The number of vertices of an        int vertex_num;//figure        List<node > * graph_list;//adjacency table        vector<graphnode> nodearr;//Save an array of each vertex information public            :        graph () {}        graph ( char* graph[], int edgenum);         ~graph ();        void print ();        Vector<int> Toposort ();//Topology Sort    private:        vector<int> get_graph_value (char* graph[], int columns );        void Addedge (char* graph[], int columns);};

Topological sort member functions:
/**************************************************  Function Name: Toposort () *  function Description: Sort the topology of the vertices in the diagram *  parameter list: none *  return Result: Returns the result of the vertex topology sort *************************************************/vector<int> graph::toposort () {    vector<int> Toposortarr;    for (int count = 0; count < Vertex_num; ++count) {        //finds a vertex with a 0-in dimension        int i;        for (i = 0; i < Vertex_num; ++i) {            if (Nodearr[i].indegree = = 0) && (Nodearr[i].vertex! =-1))                break;< c11/>}        if (i = = vertex_num) break            ;        At this point, the penetration of vertex i is 0        //delete the point and delete the edge adjacent to the point        //And the vertex I connected to the vertex of the degree minus 1        nodearr[i].indegree = 1;        for (List<node>::iterator it = Graph_list[i].begin (); It! = Graph_list[i].end (); ++it) {            nodearr[(*it). vertex].indegree--;        }        Toposortarr.push_back (i);    }    return Toposortarr;}

Test function:1, read the data in the diagram file, the data format is as follows:
0,0,1,11,0,2,22,0,3,1

The 1th column is the edge number, the 2nd column is the beginning of the edge, the 3rd column is the end of the edge, and the 4th column is the weight of the edge.
/***************************************************************** function Name: read_file* function Description: Read the data information of the graph in the file * parameter list: Buff is the The image information read by the file is saved to the two-dimensional array that the buff points to. * Spec is the maximum number of edges allowed in a file * filename is the diagram file to open * return result: no ************************** /int Read_file (char * * Const buff, const unsigned int spec, const char * const file    Name) {FILE *FP = fopen (filename, "R");        if (fp = = NULL) {printf ("Fail to open file%s,%s.\n", filename, strerror (errno));    return 0;    } printf ("Open file%s ok.\n", filename);    Char Line[max_line_len + 2];    unsigned int cnt = 0;        while (CNT < spec) &&!feof (FP)) {line[0] = 0;        Fgets (line, Max_line_len + 2, FP);        if (line[0] = = 0) continue;        BUFF[CNT] = (char *) malloc (Max_line_len + 2);        strncpy (buff[cnt], line, Max_line_len + 2-1);        BUFF[CNT][4001] = 0;    cnt++;    } fclose (FP); printf ("There is%d lines in file%s.\n", CNT,filename); return CNT;}

2. Release the information of the diagram just read
/*****************************************************************   function Name: release_buff*   Function Description: Release data information for the graph in the file you just read *   parameter list: Buff is a graph message pointing to a file read *             Valid_item_num refers to the number of edges in the graph *   return result: void************************ /void Release_buff (char * * const buff, const int valid_item_num) {for    ( int i = 0; i < Valid_item_num; i++) Free        (Buff[i]);}

3. Main test function
int main (int argc, char *argv[]) {    char *topo[5000];    int edge_num;    char *demand;    int demand_num;    Char *topo_file = argv[1];    Edge_num = Read_file (topo, topo_file);    if (Edge_num = = 0)    {        printf ("Please input valid topo file.\n");        return-1;    }    Graph G (topo, edge_num);    G.print ();    vector<int> Toposortarr = G.toposort ();    cout << "Results of topological sequencing:";    for (unsigned i = 0; i < toposortarr.size (); ++i)        cout << toposortarr[i] << "";    cout << Endl;    Release_buff (topo, edge_num); return 0;}

source code for the graph class:
#ifndef graph_h#define graph_h#include <list> #include <iostream> #include <vector> #include < stdlib.h> #include <string.h> #include <algorithm> #include <iterator> #include <stdio.h># Include <errno.h> #include <unistd.h> #include <signal.h>using namespace std; #define Max_vertex_num 600//The data structure that holds each vertex information struct graphnode{int vertex;//the current vertex designator int indegree;//The current vertex's entry int topnum;//The order of the topological ordering of the current vertex};//the section Point information typedef struct node{int edge_num;//boundary number int src;//source point int vertex;//self int weight;//edge weight}node; /******************************************************** class Name: adjacency table Diagram *********************************************  /class graph{Private:int edge_num;//the number of edges of the graph int vertex_num;//the vertices of the graph list<node> * graph_list;//adjacency table vector<graphnode> nodearr;//holds an array of each vertex information public:graph () {} Graph (ch         ar* graph[], int edgenum);        ~graph ();   void print ();     Vector<int> Toposort ();//Topology sort private:vector<int> get_graph_value (char* graph[], int columns); void Addedge (char* graph[], int columns);};/ Function name: Toposort () * Function Description: Sort the topology of the vertices in the diagram * parameter list: none * Return Result: Returns the result after the vertex topology is sorted * /vector<int> Graph::toposort () {vector<int>    Toposortarr;        for (int count = 0; count < Vertex_num; ++count) {//finds a vertex with a 0-in dimension int i;                for (i = 0; i < Vertex_num; ++i) {if (Nodearr[i].indegree = = 0) && (Nodearr[i].vertex! =-1))        Break        } if (i = = vertex_num) break;        At this point, the penetration of vertex i is 0//delete the point and delete the edge adjacent to the point//and the vertex I connected to the vertex of the degree minus 1 nodearr[i].indegree = 1; for (List<node>::iterator it = Graph_list[i].begin (); It! = Graph_list[i].end (); ++it) {nodearr[(*it). Vert        ex].indegree--;    } toposortarr.push_back (i); } RetuRN Toposortarr;} /************************************************** function Name: print* function Description: Outputs the information of the graph to the standard output * parameter list in the form of an adjacency table: none * return result: no ********** /void Graph::p rint () {cout << **************************************     "<< Endl;  for (int i = 0, i < max_vertex_num; ++i) {for (int i = 0; i < Vertex_num; ++i) {if (Graph_list[i].begin ()            ! = Graph_list[i].end ()) {cout << i << "--"; for (List<node>::iterator it = Graph_list[i].begin (); It! = Graph_list[i].end (); ++it) {cout <<            (*it). Vertex << "(Side number:" << (*it). Edge_num << ", Weight:" << (*it). Weight << ")--";        } cout << "NULL" << Endl; }} cout << "******************************************************************" << Endl; }/************************************************** function Name: get_graph_value* function Description: Each of the graphsThe information of the edge is saved to an array * parameter list: graph: Two-dimensional array pointing to graph information columns: The first side of the graph * returns results: no ************************************************    */vector<int> Graph::get_graph_value (char* graph[], int columns) {vector<int> v;    Char buff[20];    int i = 0, j = 0, Val;    memset (Buff, 0, 20);            while ((graph[columns][i]! = ' \ n ') && (graph[columns][i]! = ') ') {if (graph[columns][i]! = ', ') {            BUFF[J] = Graph[columns][i];        j + +;            } else{j = 0;             val = atoi (buff);            V.push_back (Val);        memset (Buff, 0, 20);    } i++;     } val = atoi (buff);    V.push_back (Val); return v;}             /************************************************** function Name: addedge* function Description: Add information for each edge of the graph to the adjacency table of the graph * parameter list: graph: A two-dimensional array pointing to graph information Columns: The first few sides of the graph * return result: no *************************************************/void Graph::addedge (char* graph[], int colu    MNS) {node node;    Vector<int> v = get_graph_value (graph, columns); Node.Edge_num = v[0];    NODE.SRC = v[1];    Node.vertex = v[2];    Node.weight = v[3];    The total number of vertices, based on the label of the vertex, if (Node.vertex > Vertex_num) vertex_num = Node.vertex; To consider duplicate edges, but the weights of the edges are different for (list<node>::iterator it = Graph_list[node.src].begin (); It! = Graph_list[node.src].end ( );  ++it) {if ((*it). Vertex = = Node.vertex) {if ((*it). Weight > Node.weight) {(*it). Weight =               Node.weight;        } return;    }}//Writes information to the array where each vertex is saved Nodearr[node.src].vertex = NODE.SRC;    Nodearr[node.vertex].vertex = Node.vertex; nodearr[node.vertex].indegree++;//, plus 1 graph_list[node.src].push_back (node);}  /************************************************** Function Name: constructor * Function Description: Save the information of the diagram as an adjacency table and save the vertices that must pass * Parameter list: graph: Two-dimensional array pointing to graph information edgenum: number of edges of graph * return result: no *************************************************/graph::graph (ch     ar* graph[], int edgenum): Nodearr (max_vertex_num) {edge_num = Edgenum;    Vertex_num = 0; graph_list = new list<node>[max_vertex_num+1];        Initializes the array that holds the vertex information if vertext=-1 indicates that there is no vertex for (int i = 0; i < Max_vertex_num; ++i) {Nodearr[i].vertex =-1;        Nodearr[i].indegree = 0;    Nodearr[i].topnum =-1;       } for (int i = 0; i < Edgenum; ++i) {Addedge (graph, I); } vertex_num++;} /************************************************** function Name: destructor * Function Description: Release dynamically allocated memory * parameter list: none * return result: no ********************* /graph::~graph () {delete[] graph_list;} #endif

to test the source code of the function:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include < time.h> #include <sys/timeb.h> #include <errno.h> #include <unistd.h> #include <signal.h># Include <stdio.h> #include "graphTopoSort.h" #define Max_line_len 4000int read_file (char * * Const BUFF, const unsigned int spec, const char * const filename), void Release_buff (char * * const buff, const int valid_item_num); int main (i    NT ARGC, char *argv[]) {char *topo[5000];    int edge_num;    Char *demand;    int demand_num;    Char *topo_file = argv[1];    Edge_num = Read_file (topo, topo_file);        if (Edge_num = = 0) {printf ("Please input valid topo file.\n");    return-1;    } Graph G (topo, edge_num);    G.print ();    vector<int> Toposortarr = G.toposort ();    cout << "Results of topological sequencing:";    for (unsigned i = 0; i < toposortarr.size (); ++i) cout << toposortarr[i] << "";    cout << Endl; Release_bufF (topo, edge_num); return 0;} /***************************************************************** function Name: read_file* function Description: Read the data information of the graph in the file * parameter list: Buff is the The image information read by the file is saved to the two-dimensional array that the buff points to. * Spec is the maximum number of edges allowed in a file * filename is the diagram file to open * return result: no ************************** /int Read_file (char * * Const buff, const unsigned int spec, const char * const file    Name) {FILE *FP = fopen (filename, "R");        if (fp = = NULL) {printf ("Fail to open file%s,%s.\n", filename, strerror (errno));    return 0;    } printf ("Open file%s ok.\n", filename);    Char Line[max_line_len + 2];    unsigned int cnt = 0;        while (CNT < spec) &&!feof (FP)) {line[0] = 0;        Fgets (line, Max_line_len + 2, FP);        if (line[0] = = 0) continue;        BUFF[CNT] = (char *) malloc (Max_line_len + 2);        strncpy (buff[cnt], line, Max_line_len + 2-1);        BUFF[CNT][4001] = 0;    cnt++;    } fclose (FP); printf ("There is%d Lines in file%s.\n ", CNT, filename); return CNT;}   /***************************************************************** function Name: release_buff* function Description: Release data information for the graph in the file you just read * Parameter list: Buff is a graph message pointing to a file read * Valid_item_num refers to the number of edges in the graph * return result: void**************************************************** /void Release_buff (char * * const buff, const int valid_item_num) {for (int i = 0; i < valid_item_num; I + +) Free (buff[i]);}

test Case:
0,1,2,11,1,3,12,1,4,13,2,4,14,2,5,15,3,6,16,4,3,17,4,6,18,4,7,19,5,4,110,5,7,111,7,6,1

Operation Result:

Data structure and algorithm--a topological sort of a direction-free graph C + + implementation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.