数据结构—关键路径
原理:参考趣学数据结构
代码:
#include<stdio.h>
#include<stdlib.h>
#include "stack.h"
#define typeNode int
#define N 100
int degree[N];
int result[N];
int ve[N];
int vl[N];
int ZNodeMatrix[N][N];
typedef struct dNode {
int data;
struct dNode * next;
}dNode;
typedef struct mNode {
typeNode data;
dNode * first;
}mNode;
typedef struct {
mNode vNode[N];
int vNum, eNum;
}zNode;
void init(zNode &ZNode) {
printf("规定顶点从0开始取\n");
scanf_s("%d%d", &ZNode.vNum, &ZNode.eNum);
for (int i = 0; i < ZNode.vNum; i++) {
scanf_s("%d", &ZNode.vNode[i].data);
ZNode.vNode[i].first = NULL;
}
for (int i = 0; i < ZNode.eNum; i++) {
int u, v,weight;
scanf_s("%d%d%d", &u, &v,&weight);
dNode* p = new dNode();
ZNodeMatrix[u][v] = weight;
p->data = v;
p->next = ZNode.vNode[u].first;
ZNode.vNode[u].first= p;
}
}
void print(zNode ZNode) {
printf("遍历链表:\n");
for (int i = 0; i < ZNode.vNum; i++) {
dNode* temp = ZNode.vNode[i].first;
printf("%d ->", ZNode.vNode[i].data);
while(temp){
printf("%d ->",temp->data);
temp = temp->next;
}
printf("NULL\n");
}
}
void calculate(zNode ZNodeReverse) {
for (int i = 0; i < ZNodeReverse.vNum; i++) {
int tempLength = 0;
dNode* p = new dNode();
p = ZNodeReverse.vNode[i].first;
while (p) {
tempLength ++;
p = p->next;
}
degree[i] = tempLength;
}
}
bool tuoPuSort(zNode ZNode,int result[],stack &Stack) {
int count = 0;
for (int i = 0; i < ZNode.vNum; i++) {
if (!degree[i]) {
push(Stack, i);
}
}
while (!empty(Stack)) {
dNode* p ;
int tempV = getTop(Stack);
result[count] = tempV;
count++;
int e=0;
pop(Stack, e);
p = ZNode.vNode[tempV].first;
while (p) {
int v = p->data;
degree[v]--;
if (!degree[v]) {
push(Stack, v);
}
p = p->next;
}
}
if (count < ZNode.vNum) {
return false;
}
else {
return true;
}
}
void keyPath(zNode ZNode) {
int k;
for (int i = 0; i < ZNode.vNum; i++) {
ve[i] = 0;
}
for (int i = 0; i < ZNode.vNum; i++) {
k = result[i];
dNode* p = ZNode.vNode[k].first;
while (p != NULL) {
int j = p->data;
if (ve[k] + ZNodeMatrix[k][j] > ve[j]) {
ve[j] = ve[k] + ZNodeMatrix[k][j];
}
p = p->next;
}
}
for (int i = 0; i < ZNode.vNum; i++) {
vl[i] = ve[result[ZNode.vNum - 1]];
}
for (int i = ZNode.vNum-1; i >=0 ; i--) {
k = result[i];
dNode* p = ZNode.vNode[k].first;
while (p != NULL) {
int j = p->data;
if (vl[k]>vl[j]- ZNodeMatrix[k][j]) {
vl[k] = vl[j] - ZNodeMatrix[k][j];
}
p = p->next;
}
}
int sum = 0;
printf("关键路径如下:\n");
for (int i = 0; i < ZNode.vNum; i++) {
k = result[i];
dNode* p = ZNode.vNode[k].first;
while (p != NULL) {
int j = p->data;
int e = ve[k];
int l = vl[j] - ZNodeMatrix[k][j];
if (e == l) {
sum+= ZNodeMatrix[k][j];
printf("(%d,%d) ", k, j);
}
p = p->next;
}
}
printf("关键路径长度为%d:\n",sum);
}
int main() {
zNode ZNode,ZNodeReverse;
printf("邻接表的构造:\n");
init(ZNode);
print(ZNode);
printf("逆邻接表的构造:\n");
init(ZNodeReverse);
print(ZNodeReverse);
calculate(ZNodeReverse);
stack Stack;
init(Stack);
printf("拓扑序列如下: ");
if (tuoPuSort(ZNode, result,Stack)) {
printf("\n可以构成拓扑序列!");
};
for (int i = 0; i < ZNode.vNum; i++) {
printf("%d ", result[i]);
}
printf("\n");
keyPath(ZNode);
system("pause");
return 0;
}
测试截图:
![请添加图片描述](https://img-blog.csdnimg.cn/2b54d07c1b764f02ac8ab31d7e8ff337.png)
时间复杂度O(n+e),空间复杂度O(n+e)
如果存在什么问题,欢迎批评指正!谢谢!