图是由定点的非空有限集合V与变得集合E组成的,其形式化定义为:G = (V, E),若图中的每一条边是没有方向的则称G为无向图,否则称为有向图。图的表示方法有邻接矩阵和邻接表表示法。图的常见算法有深度优先搜索,广度优先搜索,Prim算法,dijsktra算法,floyd算法,拓扑排序和关键路径。我用C++进行了实现,代码如下,具体的算法请上网搜索。
图的邻接矩阵表示:
#include <iostream>
#include <climits>
#include <sstream>
#include <queue>
#include <string>
#include <stack>
#include <cstring>
#include <vector>
using namespace std;
const bool UNDIGRAPH = 0;
struct Graph{
string *vertexLabel;//the number of the labels is equal to vertexes
int vertexes;
int edges;
int **AdjMat;
bool *visited;
int *distance;
int *path;
};
void buildGraph(Graph *&graph, int n) {
if (graph == NULL)
{
graph = new Graph();
graph->vertexes = n;
graph->edges = 0;
graph->AdjMat = new int *[n];
graph->vertexLabel = new string[n];
graph->visited = new bool[n];
graph->distance = new int[n];
graph->path = new int[n];
for (int i = 0; i < graph->vertexes; i++)
{
stringstream ss;
ss<<"v" << i+1;
ss >> graph->vertexLabel[i];
graph->visited[i] = false;
graph->distance[i] = INT_MAX;
graph->path[i] = -1;
graph->AdjMat[i] = new int[n];
if(UNDIGRAPH)
memset(graph->AdjMat[i],0, n * sizeof(int));
else
for (int j = 0; j < graph->vertexes; j++)
{
if(i == j)
graph->AdjMat[i][j] = 0;
else
graph->AdjMat[i][j] = INT_MAX;
}
}
}
}
void emptyGraph(Graph *graph) {
if (graph == nullptr) {
return;
}
delete []graph->vertexLabel;
delete []graph->visited;
delete []graph->distance;
delete []graph->path;
for (int i = 0;i < graph->vertexes;i++) {
delete []graph->AdjMat[i];
}
delete []graph->AdjMat;
delete graph;
}
void addEdge(Graph *graph, int v1, int v2, int weight) {
if (graph == nullptr) {
return;
}
if ((v1 < 0 || v1 > graph->vertexes) || (v2 < 0 || v2 > graph->vertexes)) {
return;
}
if (v1 == v2) {
return;
}
if (UNDIGRAPH) {
if (graph->AdjMat[v1][v2] == 0) {
graph->edges++;
}
graph->AdjMat[v1][v2] = graph->AdjMat[v2][v1] = weight;
}
else {
if (graph->AdjMat[v1][v2] == 0 || graph->AdjMat[v1][v2] == INT_MAX)
graph->edges++;
graph->AdjMat[v1][v2] = weight;
}
}
void removeEdges(Graph *graph, int v1, int v2) {
if (graph == nullptr) {
return;
}
if ((v1 < 0 || v1 > graph->vertexes) || (v2 < 0 || v2 > graph->vertexes)) {
return;
}
if (v1 == v2) {
return;
}
if (UNDIGRAPH)
{
if (graph->AdjMat[v1][v2] == 0)//not exists,return
return;
graph->AdjMat[v1][v2] = graph->AdjMat[v2][v1] = 0;
graph->edges--;
}
else
{
if (graph->AdjMat[v1][v2] == 0 || graph->AdjMat[v1][v2] == INT_MAX)//not exists,return
return;
graph->AdjMat[v1][v2] = INT_MAX;
graph->edges--;
}
}
void clearVisit(Graph *graph) {
for (int i = 0;i < graph->vertexes;i++) {
graph->visited[i] = false;
}
}
void clearDistance(Graph *graph) {
for (int i = 0;i < graph->vertexes;i++) {
graph->distance[i] = INT_MAX;
}
}
void clearPath(Graph *graph) {
for (int i = 0;i < graph->vertexes;i++) {
graph->path[i] = -1;
}
}
int getIndegree(Graph *graph, int v) {
if (graph == NULL) {
return -1;
}
if (v < 0 || v > graph->vertexes) {
return -2;
}
if (UNDIGRAPH) {
return -3;
}
int degree = 0;
for (int i = 0;i < graph->vertexes;i++) {
if(graph->AdjMat[i][v] != 0 &am