数据结构—图的操作与应用—第10关:求AOV网(邻接表存储)的拓扑排序算法


任务描述

本关任务:AOV网的存储结构为邻接表,要求编写函数实现AOV网的拓扑排序算法。

相关知识

拓扑排序基本概念

G=(V,E)是一个具有n个顶点的有向图,图中用顶点表示活动,用边表示活动之间的优先关系,这样的有向图称为用顶点表示活动的网,简称AOV(Activity On vertex Network)网

该网中顶点序列v1​、v2​、…、vn​称为一个拓扑序列,当且仅当该顶点序列满足下列条件: 若<vi​,vj​>是图中的边(即从顶点vi​到顶点vj​有一条路径),则在序列中顶点vi​必须排在顶点vj​之前。

在一个有向图中找一个拓扑序列的过程称为拓扑排序

例如,计算机专业的学生必须完成一系列规定的基础课和专业课才能毕业,假设这些课程的名称与相应编号如下表所示。

课程代号课程名称先修课
C1高等数学
C2程序设计
C3离散数学C1
C4数据结构C2,C3
C5编译原理C2,C4
C6操作系统C4,C7
C7计算机组成原理C2

AOV网示例图

对这个有向图进行拓扑排序可得到拓扑序列:

拓扑排序序列

拓扑排序算法思想

(1)从AOV网中选择一个没有前驱(即入度为0)的顶点并且输出它。 (2)从AOV网中删去该顶点,并且删去从该顶点发出的全部有向边。 (3)重复上述两步,直到剩余的网中不再存在没有前驱的顶点为止。

对任一有向图进行拓扑排序有两种结果:

  • 图中全部顶点都包含在拓扑序列中,这说明该图中不存在回路

  • 图中部分顶点未被包含在拓扑序列中,这说明该图中存在回路

所以可以采用拓扑排序判断一个有向图中是否存在回路,如果此有向图没有回路,则此有向图为AOV网。

不论图的存储结构为邻接矩阵还是邻接表,拓扑排序算法思想是一致的,只是计算图G每个顶点的入度过程中具体操作不同。

用邻接矩阵存储图时,定义函数计算图G每个顶点的入度,并且保存在indegree数组:

 
  1. void FindInDegree(MGraph G,int indegree[])
  2. { //计算图G每个顶点的入度,并且保存在indegree数组
  3. int i,j;
  4. for(i=0;i<G.vexnum;i++)
  5. indegree[i]=0; /* 赋初值 */
  6. for(i=0;i<G.vexnum;i++)
  7. for(j=0;j<G.vexnum;j++)
  8. if( G.arcs [j][i].adj == 1)
  9. indegree[i]++;
  10. }

用邻接表存储图时,定义函数计算图G每个顶点的入度,并且保存在indegree数组:

 
  1. void FindInDegree(ALGraph G,int indegree[])
  2. { //计算图G每个顶点的入度,并且保存在indegree数组
  3. int i;
  4. ArcNode *p;
  5. for(i=0;i<G.vexnum;i++)
  6. indegree[i]=0; /* 赋初值 */
  7. for(i=0;i<G.vexnum;i++)
  8. {
  9. p=G.vertices[i].firstarc;
  10. while(p)
  11. {
  12. indegree[p->data.adjvex]++;
  13. p=p->nextarc;
  14. }
  15. }
  16. }

编程要求

有向图的存储结构为邻接表,编写函数实现图的拓扑排序算法:

  • int TopologicalSort(ALGraph G);// 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0

如果此有向图没有回路,则此有向图为AOV网。

测试说明

平台会对你编写的代码进行测试:

测试输入: 0 lt6.txt

输入说明: 第一行输入0,表示输入图的类型为有向图。 第二行输入文件名,该文件里保存了图的数据信息,内容如下: 7 7 高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理 高等数学 离散数学 离散数学 数据结构 数据结构 操作系统 数据结构 编译原理 程序设计 计算机组成原理 程序设计 编译原理 计算机组成原理 操作系统

第1行为图的顶点的个数n; 第2行为图的边的条数m; 第3行至第n+2行是n个顶点的数据; 第n+3行至第n+m+2行是m条边的数据;

预期输出: 有向图 7个顶点: 高等数学 程序设计 离散数学 数据结构 编译原理 操作系统 计算机组成原理 7条弧(边): 高等数学→离散数学 程序设计→编译原理 程序设计→计算机组成原理 离散数学→数据结构 数据结构→编译原理 数据结构→操作系统

计算机组成原理→操作系统 输出有向图g的拓扑序列: 程序设计 计算机组成原理 高等数学 离散数学 数据结构 操作系统 编译原理

输出说明: 第一行输出图的类型。 第二部分起输出图的顶点和边的数据信息。 第三部分输出有向图的一个拓扑序列,若有回路,则输出提示此有向图有回路。

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h>
#include<limits.h>  
#include<iostream>
using namespace std;

#define INFINITY 4270000 // 用整型最大值代替∞ 

#include"ALGraph.h"

#include"sqstack.h"

void FindInDegree(ALGraph G,int indegree[]); // 求顶点的入度

int TopologicalSort(ALGraph G);// 有向图G采用邻接表存储结构。若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0
	
int main()
{
	ALGraph g;
	CreateGraphF(g); // 利用数据文件创建无向图
	Display(g); // 输出无向图
	printf("输出有向图g的拓扑序列:\n");
	TopologicalSort(g); // 输出有向图f的拓扑序列  
	return 0;
}

void FindInDegree(ALGraph G,int indegree[])
{ //计算图G每个顶点的入度,并且保存在indegree数组
	int i;
	ArcNode *p;
	for(i=0;i<G.vexnum;i++)
		indegree[i]=0; /* 赋初值 */
	for(i=0;i<G.vexnum;i++)
	{
		p=G.vertices[i].firstarc;
		while(p)
		{
			indegree[p->data.adjvex]++;
			p=p->nextarc;
		}
	}
}
int TopologicalSort(ALGraph G)
{   // 有向图G采用邻接表存储结构。
	// 若G无回路,则输出G的顶点的一个拓扑序列并返回1,否则返回0。
	/********** Begin **********/    
    int i,k,count=0;
    int indegree[MAX_VERTEX_NUM];
    SqStack S;
    ArcNode *p;
    FindInDegree(G,indegree);
    InitStack(S);
    for(i=0;i<G.vexnum;++i)
        if(!indegree[i])
            Push(S,i);
    while(!StackEmpty(S)){
        Pop(S,i);
        printf("%s ",G.vertices[i].data);
        ++count;
        for(p=G.vertices[i].firstarc;p;p=p->nextarc){
            k=p->data.adjvex;
            if(!(--indegree[k]))
                Push(S,k);
        }
    }
    if(count<G.vexnum){
        printf("\n此有向图有回路\n");
        return 0;
    }
    else
    return 1;
	/********** End **********/
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值