Date Structure: Graph
Represent graph structure with adjacency list
Basical Structure
#pragma once
#include "Head.h"
#include "Stack.h"
#include <iostream>
#define MAX_VERTEX_NUM 20
#define VertexType char
typedef enum
{
DG,
DN,
UDG,
UDN
} GraphKind;
typedef struct ArcNode
{
int adjvex;
struct ArcNode* nextarc;
int weight;
} ArcNode;
typedef struct VNode
{
VertexType data;
ArcNode* firstarc;
} VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
AdjList vertices;
int vexnum, arcnum;
GraphKind Kind;
} ALGraph;
Create
void CreateALGraph(ALGraph& ALG);
void CreateDG(ALGraph& ALG);
void CreateDN(ALGraph& ALG);
void CreateUDG(ALGraph& ALG);
void CreateUDN(ALGraph& ALG);
void CreateALGraph(ALGraph& ALG)
{
printf("请输入构造图的类型: \n");
std::string temp;
std::cin >> temp;
if (temp == "DG")
ALG.Kind = DG;
else if (temp == "DN")
ALG.Kind = DN;
else if (temp == "UDG")
ALG.Kind = UDG;
else if (temp == "UDN")
ALG.Kind = UDN;
switch (ALG.Kind)
{
case DG:
CreateDG(ALG);
return;
case DN:
CreateDN(ALG);
return;
case UDG:
CreateUDG(ALG);
return;
case UDN:
CreateUDN(ALG);
return;
}
}
void CreateDN(ALGraph& ALG)
{
InitALGraph(ALG);
int from, to, value;
ArcNode* q;
std::cout << "请输入顶点数和边数: \n";
std::cin >> ALG.vexnum >> ALG.arcnum;
std::cout << "读入顶点信息,建立顶点表: \n";
for (int i = 0; i < ALG.vexnum; i++)
std::cin >> ALG.vertices[i].data;
std::cout << "输入边(Vi,Vj)上的下标i, 下标j, 权w: \n";
for (int i = 0; i < ALG.arcnum; i++)
{
std::cin >> from >> to >> value;
ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = to;
p->weight = value;
p->nextarc = NULL;
if (ALG.vertices[from].firstarc)
{
for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[from].firstarc = p;
}
}
void CreateDG(ALGraph& ALG)
{
InitALGraph(ALG);
int from, to;
ArcNode* q;
std::cout << "请输入顶点数和边数: \n";
std::cin >> ALG.vexnum >> ALG.arcnum;
std::cout << "读入顶点信息,建立顶点表: \n";
for (int i = 0; i < ALG.vexnum; i++)
std::cin >> ALG.vertices[i].data;
std::cout << "输入边(Vi,Vj)上的下标i, 下标j\n";
for (int i = 0; i < ALG.arcnum; i++)
{
std::cin >> from >> to;
ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = to;
p->weight = 1;
p->nextarc = NULL;
if (ALG.vertices[from].firstarc)
{
for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[from].firstarc = p;
}
}
void CreateUDG(ALGraph& ALG)
{
InitALGraph(ALG);
int from, to;
ArcNode* q;
std::cout << "请输入顶点数和边数: \n";
std::cin >> ALG.vexnum >> ALG.arcnum;
std::cout << "读入顶点信息,建立顶点表: \n";
for (int i = 0; i < ALG.vexnum; i++)
std::cin >> ALG.vertices[i].data;
std::cout << "输入边(Vi,Vj)上的下标i, 下标j\n";
for (int i = 0; i < ALG.arcnum; i++)
{
std::cin >> from >> to;
ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = to;
p->weight = 1;
p->nextarc = nullptr;
if (ALG.vertices[from].firstarc)
{
for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[from].firstarc = p;
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = from;
p->weight = 1;
p->nextarc = nullptr;
if (ALG.vertices[to].firstarc)
{
for (q = ALG.vertices[to].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[to].firstarc = p;
}
}
void CreateUDN(ALGraph& ALG)
{
InitALGraph(ALG);
int from, to, value;
ArcNode* q;
std::cout << "请输入顶点数和边数: \n";
std::cin >> ALG.vexnum >> ALG.arcnum;
std::cout << "读入顶点信息,建立顶点表: \n";
for (int i = 0; i < ALG.vexnum; i++)
std::cin >> ALG.vertices[i].data;
std::cout << "输入边(Vi,Vj)上的下标i, 下标j, 权w: \n";
for (int i = 0; i < ALG.arcnum; i++)
{
std::cin >> from >> to >> value;
ArcNode* p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = to;
p->weight = value;
p->nextarc = NULL;
if (ALG.vertices[from].firstarc)
{
for (q = ALG.vertices[from].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[from].firstarc = p;
p = (ArcNode*)malloc(sizeof(ArcNode));
p->adjvex = from;
p->weight = value;
p->nextarc = NULL;
if (ALG.vertices[to].firstarc)
{
for (q = ALG.vertices[to].firstarc; q->nextarc; q = q->nextarc)
;
q->nextarc = p;
}
else
ALG.vertices[to].firstarc = p;
}
}
Predecessor-free vertex-first algorithm
void FindInDegree(ALGraph ALG, int indegree[]);
void FindOutDegree(ALGraph ALG, int outdegree[]);
int TopologicalSort(ALGraph ALG);
void FindInDegree(ALGraph ALG, int indegree[])
{
ArcNode* q;
for (int i = 0; i < ALG.vexnum; i++)
for (q = ALG.vertices[i].firstarc; q; q = q->nextarc)
indegree[q->adjvex]++;
}
void FindOutDegree(ALGraph ALG, int outdegree[])
{
ArcNode* q;
for (int i = 0; i < ALG.vexnum; i++)
for (q = ALG.vertices[i].firstarc; q; q = q->nextarc)
outdegree[i]++;
}
int TopologicalSort(ALGraph ALG)
{
int indegree[MAX_VERTEX_NUM] = {0};
FindInDegree(ALG, indegree);
#if TEST
printf("检查入度是否正确: \n") for (int i = 0; i < ALG.vexnum; i++)
std::cout
<< ALG.vertices[i].data << " " << indegree[i] << std::endl;
printf("\n");
#endif
SqStack<int> S{};
InitStack(S);
for (int i = 0; i < ALG.vexnum; i++)
if (!indegree[i])
Push(S, i);
int temp;
int count = 0;
while (!StackEmpty(S))
{
Pop(S, temp);
#if TEST
printf("顶点编号: %d 顶点值: %c\n", temp, ALG.vertices[temp].data);
#endif
++count;
for (ArcNode* p = ALG.vertices[temp].firstarc; p; p = p->nextarc)
{
temp = p->adjvex;
if (!(--indegree[temp]))
Push(S, temp);
}
}
if (count < ALG.vexnum)
return -1;
else
return 1;
}
AOE Graph
int TopologicalOrder(ALGraph ALG, SqStack<int>& T, int eventEarly[]);
int CriticalPath(ALGraph ALG);
int TopologicalOrder(ALGraph ALG, SqStack<int>& T, int eventEarly[])
{
int indegree[MAX_VERTEX_NUM] = {0};
FindInDegree(ALG, indegree);
for (int i = 0; i < ALG.vexnum; i++)
eventEarly[i] = 0;
SqStack<int> S{};
InitStack(S);
for (int i = 0; i < ALG.vexnum; i++)
if (!indegree[i])
Push(S, i);
int temp;
int count = 0;
int k;
while (!StackEmpty(S))
{
Pop(S, k);
Push(T, k);
++count;
for (ArcNode* p = ALG.vertices[k].firstarc; p; p = p->nextarc)
{
temp = p->adjvex;
if (!(--indegree[temp]))
Push(S, temp);
eventEarly[temp] = MAX(eventEarly[k] + p->weight, eventEarly[temp]);
}
}
#if TEST
printf("检验所求的eventEarly数组的值是否正确: \n");
for (int i = 0; i < ALG.vexnum; i++)
std::cout << ALG.vertices[i].data << ' ' << eventEarly[i] << std::endl;
#endif
if (count < ALG.vexnum)
return -1;
else
return 1;
}
int CriticalPath(ALGraph ALG)
{
int eventEarly[MAX_VERTEX_NUM] = {0};
int eventLast[MAX_VERTEX_NUM] = {0};
for (int i = 0; i < MAX_VERTEX_NUM; i++)
eventEarly[i] = 0;
SqStack<int> T{};
TopologicalOrder(ALG, T, eventEarly);
int outdegree[MAX_VERTEX_NUM];
for (int i = 0; i < ALG.vexnum; i++)
outdegree[i] = 0;
FindOutDegree(ALG, outdegree);
int end;
for (int i = 0; i < ALG.vexnum; i++)
if (outdegree[i] == 0)
{
end = i;
break;
}
for (int i = 0; i < MAX_VERTEX_NUM; i++)
eventLast[i] = INF;
eventLast[end] = eventEarly[end];
int j;
int k;
ArcNode* p;
Pop(T, j);
while (!StackEmpty(T))
{
Pop(T, j);
for (p = ALG.vertices[j].firstarc; p; p = p->nextarc)
{
k = p->adjvex;
eventLast[j] = MIN(eventLast[j], eventLast[k] - p->weight);
}
}
#if TEST
printf("\n");
printf("检查: eventLast 和 eventEarly\n");
for (int i = 0; i < ALG.vexnum; i++)
printf("%c eventEarly: %d, eventLsat: %d\n", ALG.vertices[i].data, eventEarly[i], eventEarly[i]);
#endif
int dut;
int edgeEarly, edgeLast;
char tag;
for (j = 0; j < ALG.vexnum; j++)
{
for (p = ALG.vertices[j].firstarc; p; p = p->nextarc)
{
k = p->adjvex, dut = p->weight;
edgeEarly = eventEarly[j];
edgeLast = eventLast[k] - dut;
tag = (edgeEarly == edgeLast) ? '*' : ' ';
printf("%c -> %c: weight: %d edgeEarly: %d, edgeLast: %d %c\n", ALG.vertices[j].data, ALG.vertices[k].data, dut, edgeEarly, edgeLast, tag);
}
}
return 1;
}