数据结构---关键路径
生活随笔
收集整理的這篇文章主要介紹了
数据结构---关键路径
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構—關鍵路徑
原理:參考趣學數據結構
代碼:
#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++) {//規定頂點從0開始取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);//u頂點到v頂點有邊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]) {//對入度為0的點入棧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;//取以tempV頂點為入度點while (p) {//和tempV相連的鄰接邊的入度減1int 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)
如果存在什么問題,歡迎批評指正!謝謝!
總結
以上是生活随笔為你收集整理的数据结构---关键路径的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: e网云是怎么推广关键词的(关键词词云怎么
- 下一篇: word List16