数据结构—关键路径
原理:参考趣学数据结构
代码:
#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;
}
测试截图:
时间复杂度O(n+e),空间复杂度O(n+e)
如果存在什么问题,欢迎批评指正!谢谢!