Status TopologicalOrder(ALGraph G, Stack &T) { // 算法7.13 // 有向网G采用邻接表存储结构,求各顶点事件的最早发生时间ve(全局变量)。 // T为拓扑序列定点栈,S为零入度顶点栈。 // 若G无回路,则用栈T返回G的一个拓扑序列,且函数值为OK,否则为ERROR。 Stack S;int count=0,k; char indegree[40]; ArcNode *p; InitStack(S); FindInDegree(G, indegree); // 对各顶点求入度indegree[0..vernum-1] for (int j=0; j<G.vexnum; ++j) // 建零入度顶点栈S if (indegree[j]==0) Push(S, j); // 入度为0者进栈 InitStack(T);//建拓扑序列顶点栈T count = 0; for(int i=0; i<G.vexnum; i++) ve[i] = 0; // 初始化 while (!StackEmpty(S)) { Pop(S, j); Push(T, j); ++count; // j号顶点入T栈并计数 for (p=G.vertices[j].firstarc; p; p=p->nextarc) { k = p->adjvex; // 对j号顶点的每个邻接点的入度减1 if (--indegree[k] == 0) Push(S, k); // 若入度减为0,则入栈 if (ve[j]+p->info > ve[k]) ve[k] = ve[j]+p->info; }//for *(p->info)=dut(<j,k>) }//while if (count<G.vexnum) return ERROR; // 该有向网有回路 else return OK; } // TopologicalOrder
Status TopologicalSort(ALGraph G) { /* 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回OK, */ /* 否则返回ERROR。算法7.12 */ int i,k,count,indegree[MAX_VERTEX_NUM]; SqStack S; ArcNode *p; FindInDegree(G,indegree); /* 对各顶点求入度indegree[0..vernum-1] */ InitStack(&S); /* 初始化栈 */ for(i=0;i<G.vexnum;++i) /* 建零入度顶点栈S */ if(!indegree[i]) Push(&S,i); /* 入度为0者进栈 */ count=0; /* 对输出顶点计数 */ while(!StackEmpty(S)) { /* 栈不空 */ Pop(&S,&i); printf("%s ",G.vertices[i].data); /* 输出i号顶点并计数 */ ++count; for(p=G.vertices[i].firstarc;p;p=p->nextarc) { /* 对i号顶点的每个邻接点的入度减1 */ k=p->adjvex; if(!(--indegree[k])) /* 若入度减为0,则入栈 */ Push(&S,k); } } if(count<G.vexnum) { printf("此有向图有回路\n"); return ERROR; } else { printf("为一个拓扑序列。\n"); return OK; } }
/** * 算法7.13,有向网G采用邻接表存储,求各顶点事件的最早发生时间ve * T为拓补序列顶点栈 * 若G无回路,则用栈T返回G的一个拓补序列,且函数值为OK,否则为ERROR */ Status TopologicalSort(ALGraph G, SqStack &T, int ve[]) { SqStack S; // S为零入度栈 int indegree[MAX_VERTEX_NUM]; int count, i, j, k; int arcvalue = 0; ArcNode *p; InitStack(S); InitStack(T); FindInDegree(G, indegree); for (i = 0; i < G.vexnum; i++) { if (0 == indegree[i]) { //初始时所有入度为0的顶点入栈,此时应只有源点入栈 Push(S, i); } } count = 0; for (i = 0; i < G.vexnum; i++) { ve[i] = 0; } while (!StackEmpty(S)) { Pop(S, j); Push(T, j); ++count; for (p = G.vertices[j].firstarc; p != NULL; p = p->nextarc) { k = p->adjvex; --indegree[k]; if (0 == indegree[k]) { Push(S, k); } arcvalue = atoi(p->info); //活动时间, 将字符转成整数 if (ve[j] + arcvalue > ve[k]) { //选择最大的,这一步最关键,参看书本P184 ve[k] = ve[j] + arcvalue; } } } if (count < G.vexnum) { return ERROR; } else { return OK; } }
Status TopologicalOrder(ALGraph G,SqStack &T) { // 算法7.13 有向网G采用邻接表存储结构,求各顶点事件的最早发生时间ve(全局变量)。T为拓扑序列 // 顶点栈,S为零入度顶点栈。若G无回路,则用栈T返回G的一个拓扑序列,且函数值为OK,否则为ERROR int i,k,count=0; // 已入栈顶点数,初值为0 int indegree[MAX_VERTEX_NUM]; // 入度数组,存放各顶点当前入度数 SqStack S; ArcNode *p; FindInDegree(G,indegree); // 对各顶点求入度indegree[],在func7-1.cpp中 InitStack(S); // 初始化零入度顶点栈S printf("拓扑序列:"); for(i=0;i<G.vexnum;++i) // 对所有顶点i if(!indegree[i]) // 若其入度为0 Push(S,i); // 将i入零入度顶点栈S InitStack(T); // 初始化拓扑序列顶点栈 for(i=0;i<G.vexnum;++i) // 初始化ve[]=0(最小值,先假定每个事件都不受其他事件约束) ve[i]=0; while(!StackEmpty(S)) // 当零入度顶点栈S不空 { Pop(S,i); // 从栈S将已拓扑排序的顶点j弹出 printf("%s ",G.vertices[i].data); Push(T,i); // j号顶点入逆拓扑排序栈T(栈底元素为拓扑排序的第1个元素) ++count; // 对入栈T的顶点计数 for(p=G.vertices[i].firstarc;p;p=p->nextarc) { // 对i号顶点的每个邻接点 k=p->data.adjvex; // 其序号为k if(--indegree[k]==0) // k的入度减1,若减为0,则将k入栈S Push(S,k); if(ve[i]+*(p->data.info)>ve[k]) // *(p->data.info)是<i,k>的权值 ve[k]=ve[i]+*(p->data.info); // 顶点k事件的最早发生时间要受其直接前驱顶点i事件的 } // 最早发生时间和<i,k>的权值约束。由于i已拓扑有序,故ve[i]不再改变 } if(count<G.vexnum) { printf("此有向网有回路\n"); return ERROR; } else return OK; }
/** * 算法7.12,求拓补序列,有向图G用邻接表存储结构,若G中无回路则输出拓补序列并返回OK,否则返回ERROR */ Status TopologicalSort(ALGraph G) { int i, j, count; ArcNode *p; int indegree[MAX_VERTEX_NUM]; int stack[MAX_VERTEX_NUM]; // 模拟栈的功能 int top = 0; // 栈指针 FindInDegree(G, indegree); for (i = 0; i < G.vexnum; i++) { if (0 == indegree[i]) { //初始时所有入度为0的顶点入栈 stack[top] = i; ++top; } } count = 0; //拓补序列内顶点数计数 while (0 != top) { --top; i = stack[top]; //弹栈访问入度为0的顶点 printf("%d: %c\n", count+1, G.vertices[i].data); //输出顶点信息 ++count; //计数加1 for (p = G.vertices[i].firstarc; p != NULL; p = p->nextarc) { j = p->adjvex; //顶点的入度减1 --indegree[j]; if (0 == indegree[j]) { stack[top] = j; //入度为0顶点进栈 ++top; } } } if (count < G.vexnum) { //说明有向图中存在回路 return ERROR; } else { return OK; } }