/*
*Copyright (c)2017, School of computer and control engineering, Yantai University
*All rights reservrd.
*Author: Li Xinhao
*Completion time: November 23, 2017
*Version number: v1.0
*Problem Description: Floyd algorithm verification
The following figure is an example:
1, Edit graph.h as header file based on graph database:
#ifndef GRAPH_H_INCLUDED #define GRAPH_H_INCLUDED #define MAXV 100 / / maximum number of vertices #Define inf 32767 / / inf means ∞ #define MaxSize 100 typedef int InfoType; //The following defines the type of adjacency matrix typedef struct { int no; //Vertex number InfoType info; //Other information of vertex, where the weight of weighted graph is stored } VertexType; //Vertex Type typedef struct //Definition of Graphs { int edges[MAXV][MAXV]; //adjacency matrix int n,e; //Number of vertices, arcs VertexType vexs[MAXV]; //Store vertex information } MGraph; //Adjacency matrix types of Graphs //The following defines the adjacency table type typedef struct ANode //Node structure type of arc { int adjvex; //End position of the arc struct ANode *nextarc; //Pointer to the next arc InfoType info; //The relevant information of the arc is used to store the weight } ArcNode; typedef int Vertex; typedef struct Vnode //Types of adjacent header nodes { Vertex data; //Vertex information int count; //Store vertex access, only used in topological sorting ArcNode *firstarc; //Point to the first arc } VNode; typedef VNode AdjList[MAXV]; //AdjList is an adjacency table type typedef struct { AdjList adjlist; //Adjacency list int n,e; //Vertex number n and edge number e in the graph } ALGraph; //Adjacency table types of Graphs //Function: construct a graph stored by adjacency matrix from a 2D array reflecting the adjacency relationship of vertices in the graph //Parameter: Arr - array name. Since the formal parameter is a two-dimensional array, the number of elements in each row must be given. Here, the parameter Arr is declared as a one-dimensional array name (pointer to int) // The order of n - matrix // g - adjacency matrix data structure to be constructed void ArrayToMat(int *Arr, int n, MGraph &g); //Constructing adjacency matrix of graph with common array void ArrayToList(int *Arr, int n, ALGraph *&); //Constructing adjacency table of graph with common array void MatToList(MGraph g,ALGraph *&G);//Transforming adjacency matrix G into adjacency table G void ListToMat(ALGraph *G,MGraph &g);//Transforming adjacency table g into adjacency matrix G void DispMat(MGraph g);//Output adjacency matrix g void DispAdj(ALGraph *G);//Output adjacency table G void Ppath(int path[][MAXV],int i,int j); void Dispath(int A[][MAXV],int path[][MAXV],int n); void Floyd(MGraph g); #endif // GRAPH_H_INCLUDED
2, These functions are implemented in the source file graph.cpp file:
#include <stdio.h> #include <malloc.h> #include "graph.h" //Function: construct a graph stored by adjacency matrix from a 2D array reflecting the adjacency relationship of vertices in the graph //Parameter: Arr - array name. Since the formal parameter is a two-dimensional array, the number of elements in each row must be given. Here, the parameter Arr is declared as a one-dimensional array name (pointer to int) // The order of n - matrix // g - adjacency matrix data structure to be constructed void ArrayToMat(int *Arr, int n, MGraph &g) { int i,j,count=0; //Count is used to count the number of sides, that is, the number of non-zero elements in the matrix g.n=n; for (i=0; i<g.n; i++) for (j=0; j<g.n; j++) { g.edges[i][j]=Arr[i*n+j]; //The Arr is regarded as a two-dimensional array of n × n, and the Arr[i*n+j] is the Arr[i][j] if(g.edges[i][j]!=0 && g.edges[i][j]!=INF) count++; } g.e=count; } void ArrayToList(int *Arr, int n, ALGraph *&G) { int i,j,count=0; //Count is used to count the number of sides, that is, the number of non-zero elements in the matrix ArcNode *p; G=(ALGraph *)malloc(sizeof(ALGraph)); G->n=n; for (i=0; i<n; i++) //Set the initial value of the pointer field of all header nodes in the adjacency table G->adjlist[i].firstarc=NULL; for (i=0; i<n; i++) //Check every element in adjacency matrix for (j=n-1; j>=0; j--) if (Arr[i*n+j]!=0) //There is an edge. Consider Arr as a two-dimensional array of n × n. Arr[i*n+j] is Arr[i][j] { p=(ArcNode *)malloc(sizeof(ArcNode)); //Create a node * p p->adjvex=j; p->info=Arr[i*n+j]; p->nextarc=G->adjlist[i].firstarc; //Insert * p by head insertion G->adjlist[i].firstarc=p; } G->e=count; } void MatToList(MGraph g, ALGraph *&G) //Transforming adjacency matrix G into adjacency table G { int i,j; ArcNode *p; G=(ALGraph *)malloc(sizeof(ALGraph)); for (i=0; i<g.n; i++) //Set the initial value of the pointer field of all header nodes in the adjacency table G->adjlist[i].firstarc=NULL; for (i=0; i<g.n; i++) //Check every element in adjacency matrix for (j=g.n-1; j>=0; j--) if (g.edges[i][j]!=0) //There is an edge { p=(ArcNode *)malloc(sizeof(ArcNode)); //Create a node * p p->adjvex=j; p->info=g.edges[i][j]; p->nextarc=G->adjlist[i].firstarc; //Insert * p by head insertion G->adjlist[i].firstarc=p; } G->n=g.n; G->e=g.e; } void ListToMat(ALGraph *G,MGraph &g) //Transforming adjacency table g into adjacency matrix G { int i,j; ArcNode *p; g.n=G->n; //According to the first floor students "report" change. g.n is not assigned, the following initialization does not work g.e=G->e; for (i=0; i<g.n; i++) //Initialize adjacency matrix first for (j=0; j<g.n; j++) g.edges[i][j]=0; for (i=0; i<G->n; i++) //Assign values to adjacency matrix according to adjacency table { p=G->adjlist[i].firstarc; while (p!=NULL) { g.edges[i][p->adjvex]=p->info; p=p->nextarc; } } } void DispMat(MGraph g) //Output adjacency matrix g { int i,j; for (i=0; i<g.n; i++) { for (j=0; j<g.n; j++) if (g.edges[i][j]==INF) printf("%3s","∞"); else printf("%3d",g.edges[i][j]); printf("\n"); } } void DispAdj(ALGraph *G) //Output adjacency table G { int i; ArcNode *p; for (i=0; i<G->n; i++) { p=G->adjlist[i].firstarc; printf("%3d: ",i); while (p!=NULL) { printf("-->%d/%d ",p->adjvex,p->info); p=p->nextarc; } printf("\n"); } } void Ppath(int path[][MAXV],int i,int j) //Forward recursion to find the vertex on the path { int k; k=path[i][j]; if (k==-1) return; //Find the starting point and return Ppath(path,i,k); //Find the previous vertex k of vertex i printf("%d,",k); Ppath(path,k,j); //Find the previous vertex j of vertex k } void Dispath(int A[][MAXV],int path[][MAXV],int n) { int i,j; for (i=0; i<n; i++) for (j=0; j<n; j++) { if (A[i][j]==INF) { if (i!=j) printf("from%d reach%d No path\n",i,j); } else { printf(" from%d reach%d=>path length:%d Route:",i,j,A[i][j]); printf("%d,",i); //Starting point on output path Ppath(path,i,j); //Middle point on output path printf("%d\n",j); //End point on output path } } } void Floyd(MGraph g) { int A[MAXV][MAXV],path[MAXV][MAXV]; int i,j,k; for (i=0; i<g.n; i++) for (j=0; j<g.n; j++) { A[i][j]=g.edges[i][j]; path[i][j]=-1; } for (k=0; k<g.n; k++) { for (i=0; i<g.n; i++) for (j=0; j<g.n; j++) if (A[i][j]>A[i][k]+A[k][j]) { A[i][j]=A[i][k]+A[k][j]; path[i][j]=k; } } Dispath(A,path,g.n); //Output shortest path }
3, Complete the test in the main.cpp source file:
#include <stdio.h> #include <malloc.h> #include "graph.h" int main() { MGraph g; int A[4][4]= { {0, 5,INF,7}, {INF,0, 4,2}, {3, 3, 0,2}, {INF,INF,1,0} }; ArrayToMat(A[0], 4, g); Floyd(g); return 0; }
4, The screenshot of the test results is as follows: