拓扑排序
代码如下
有了逆邻接表的话求入度比较舒服
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MVNum 100 //最大顶点数
typedef struct ArcNode
{
int adjvex;//该边所指向的顶点的位置
struct ArcNode* next;
}ArcNode;//边结点
typedef struct VNode
{
char data;//该边所指向的顶点的位置
ArcNode* firstarc;
}VNode;//顶点
typedef struct
{
VNode vertices[MVNum]; //邻接表
VNode fvertices[MVNum]; //逆邻接表
int vexnum; //图的当前顶点数
int arcnum; //图的当前边数
}ALGraph;//Adjacency List Graph
int LocateVex(ALGraph* G, char v)//找到结点V在图G中的位置 即下标
{
for (int i = 0; i < G->vexnum; i++)
{
if (G->vertices[i].data == v)
return i;
}
cout << "没找到" << endl;
return 0;
}
void CreatALG(ALGraph* G)//邻接表表示法创建有向图
{
cout << "请输入图的总顶点数与总边数: ";
cin >> G->vexnum >> G->arcnum;//输入总顶点数 总边数
cout << "输入顶点信息: ";
for (int i = 0; i < G->vexnum; i++)//初始化
{
cin >> G->vertices[i].data;
G->vertices[i].firstarc = NULL;
G->fvertices[i].data= G->vertices[i].data;
G->fvertices[i].firstarc = NULL;
}
cout << "输入相连的结点" << endl;
char v1, v2;
for (int k = 0; k < G->arcnum; k++)//构造邻接表与逆邻接表
{
cin >> v1 >> v2; //v1-->v2
int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
ArcNode* p1 = new ArcNode;
p1->adjvex = j; //邻接点序号
p1->next = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1; //前插
ArcNode* p2 = new ArcNode;
p2->adjvex = i;
p2->next = G->fvertices[j].firstarc;
G->fvertices[j].firstarc = p2;
}
cout << "邻接表如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->vertices[i].data << "->";
ArcNode* p = G->vertices[i].firstarc;
while (p != NULL)
{
cout << G->vertices[p->adjvex].data << "->";
p = p->next;
}
cout << "->NULL" << endl;
}
cout << "逆邻接表如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->fvertices[i].data << "->";
ArcNode* p = G->fvertices[i].firstarc;
while (p != NULL)
{
cout << G->fvertices[p->adjvex].data << "->";
p = p->next;
}
cout << "->NULL" << endl;
}
}
int indegree[MVNum];//存储入度数组
void FindInDegree(ALGraph G, int indegree[]) //获取入度
{
for (int i = 0; i < G.vexnum; i++)
{
int cnt = 0;
while (G.fvertices[i].firstarc != NULL)
{
cnt++;
G.fvertices[i].firstarc = G.fvertices[i].firstarc->next;
}
indegree[i] = cnt;
}
}
int topo[MVNum];
int stack[MVNum];//辅助栈
int top = 0;
void TopologicalSort(ALGraph *G, int* topo)
{
FindInDegree(*G, indegree);
for (int i = 0; i < G->vexnum; i++)
{
if (indegree[i] == 0)
stack[top++] = i;
}
int m = 0;
while(top>=0)
{
int i = stack[--top];
topo[m++] = i;
ArcNode* p = G->vertices[i].firstarc;
while (p != NULL)
{
int k = p->adjvex;
indegree[k]--;
if (indegree[k] == 0)
{
stack[top++] = k;
}
p = p->next;
}
}
if (m < G->vexnum)
{
cout << "该图有回路" << endl;
}
else
{
cout << "拓扑序列如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->vertices[topo[i]].data << " ";
}
}
return;
}
int main()
{
ALGraph* G = new ALGraph;
CreatALG(G);
TopologicalSort(G, topo);
}
按照下图进行测试
结果如下
关键路径
代码如下
#include<iostream>
#include<stdlib.h>
using namespace std;
#define MVNum 100 //最大顶点数
typedef struct ArcNode
{
int adjvex;//该边所指向的顶点的位置
int weight;
struct ArcNode* next;
}ArcNode;//边结点
typedef struct VNode
{
char data;//该边所指向的顶点的位置
int weight;
ArcNode* firstarc;
}VNode;//顶点
typedef struct
{
VNode vertices[MVNum]; //邻接表
VNode fvertices[MVNum]; //逆邻接表
int vexnum; //图的当前顶点数
int arcnum; //图的当前边数
}ALGraph;//Adjacency List Graph
int LocateVex(ALGraph* G, char v)//找到结点V在图G中的位置 即下标
{
for (int i = 0; i < G->vexnum; i++)
{
if (G->vertices[i].data == v)
return i;
}
cout << "没找到" << endl;
return 0;
}
void CreatALG(ALGraph* G)//邻接表表示法创建有向网
{
cout << "请输入图的总顶点数与总边数: ";
cin >> G->vexnum >> G->arcnum;//输入总顶点数 总边数
cout << "输入顶点信息: ";
for (int i = 0; i < G->vexnum; i++)//初始化
{
cin >> G->vertices[i].data;
G->vertices[i].firstarc = NULL;
G->fvertices[i].data = G->vertices[i].data;
G->fvertices[i].firstarc = NULL;
}
cout << "输入相连的结点与权值" << endl;
char v1, v2;
int weight;
for (int k = 0; k < G->arcnum; k++)//构造邻接表与逆邻接表
{
cin >> v1 >> v2 >> weight; //v1-->v2
int i = LocateVex(G, v1);
int j = LocateVex(G, v2);
ArcNode* p1 = new ArcNode;
p1->weight = weight;
p1->adjvex = j; //邻接点序号
p1->next = G->vertices[i].firstarc;
G->vertices[i].firstarc = p1; //前插
ArcNode* p2 = new ArcNode;
p2->adjvex = i;
p2->next = G->fvertices[j].firstarc;
G->fvertices[j].firstarc = p2;
}
cout << "邻接表如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->vertices[i].data << "->";
ArcNode* p = G->vertices[i].firstarc;
while (p != NULL)
{
cout << G->vertices[p->adjvex].data << "->";
p = p->next;
}
cout << "NULL" << endl;
}
cout << "逆邻接表如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->fvertices[i].data << "->";
ArcNode* p = G->fvertices[i].firstarc;
while (p != NULL)
{
cout << G->fvertices[p->adjvex].data << "->";
p = p->next;
}
cout << "NULL" << endl;
}
}
int indegree[MVNum];//存储入度数组
void FindInDegree(ALGraph G, int indegree[])
{
for (int i = 0; i < G.vexnum; i++)
{
int cnt = 0;
while (G.fvertices[i].firstarc != NULL)
{
cnt++;
G.fvertices[i].firstarc = G.fvertices[i].firstarc->next;
}
indegree[i] = cnt;
}
}
int topo[MVNum];
int stack[MVNum];//辅助栈
int top = 0;
void TopologicalSort(ALGraph* G, int* topo)
{
FindInDegree(*G, indegree);
for (int i = 0; i < G->vexnum; i++)
{
if (indegree[i] == 0)
stack[top++] = i;
}
int m = 0;
while (top >= 0)
{
int i = stack[--top];
topo[m++] = i;
ArcNode* p = G->vertices[i].firstarc;
while (p != NULL)
{
int k = p->adjvex;
indegree[k]--;
if (indegree[k] == 0)
{
stack[top++] = k;
}
p = p->next;
}
}
if (m < G->vexnum)
{
cout << "该图有回路" << endl;
}
else
{
cout << "拓扑序列如下" << endl;
for (int i = 0; i < G->vexnum; i++)
{
cout << G->vertices[topo[i]].data << " ";
}
}
cout << endl;
return;
}
int ve[MVNum], vl[MVNum];
void CriticalPath(ALGraph* G) //关键路径
{
TopologicalSort(G, topo);
int n = G->vexnum;
/*----------------------每个事件的最早发生时间-----------------------*/
for (int i = 0; i < n; i++)
{
int k = topo[i];//取得拓扑排序中的顶点序号
ArcNode* p = G->vertices[k].firstarc;
while (p != NULL)
{
int j = p->adjvex;
if (ve[j] < ve[k] + p->weight)
ve[j] = ve[k] + p->weight;
p = p->next;
}
}
for (int i = 0; i < n; i++)
vl[i] = ve[n - 1]; //为最迟开始时间赋初值
/*----------------------每个事件的最迟发生时间-----------------------*/
for (int i = n - 1; i >= 0; i--)
{
int k = topo[i];
ArcNode* p = G->vertices[k].firstarc;
while (p != NULL)
{
int j = p->adjvex;
if (vl[k] > vl[j] - p->weight)
vl[k] = vl[j] - p->weight;
p = p->next;
}
}
/*----------------------判断每一个活动是否为关键活动-----------------------*/
int e = 0, l = 0;
cout << "关键路径如下" << endl;
for (int i = 0; i < n; i++)
{
ArcNode* p = G->vertices[i].firstarc;
while (p != NULL)
{
int j = p->adjvex;
e = ve[i];
l = vl[j] - p->weight;
if (e == l)
cout << G->vertices[i].data << "--" << G->vertices[j].data << endl;
p = p->next;
}
}
return;
}
int main()
{
ALGraph* G = new ALGraph;
CreatALG(G);
CriticalPath(G);
return 0;
}
按照下图进行测试
测试结果如下