数据结构 图 有向无环图

(1)如何判断一个图是不是含有环?

a. DFS,出现返回边则有环。

b. 拓扑排序,若所有的顶点都出现在拓扑排序中,则不出现环。

(2)拓扑排序

a.什么是偏序,全序?from:

http://www.programfan.com/club/showbbs.asp?id=221968

偏序是由实数中的 >= <= 抽象出来的
在一个集合F中定义一个比较关系, 这个关系不要求任意两个元素都能比较
这个关系可以任意定义,记为
<  , 但是定义的关系要满足以下3个条件
1 ) 任意a属于F,有a  <  a;               ...说明元素自己可以和自己比较
2 ) 如果a和b能比较 且a  <  b, b和c能比较,且 b  <  c
   那么a和c就能比较,且a 
<  c          ...说明比较关系具有传递性
3 ) 如果a和b能比较,且a  <  b, b  <  a, 那么a  =  b 
定义的这种满足以上3条公理的比较关系就叫偏序,和所在的集合记为( F, 
<  )

全序首先是偏序,但是比偏序多一个要求:集合中的任意两个元素都是可比的。

b.拓扑排序:

由偏序定义得到拓扑有序的操作便是拓扑排序(topological order)。

算法:

(1) 在有向图中选一个没有前驱的顶点输出。

(2) 从图中删除该定点和所有以它为尾的弧。

(3) 重复前两步,直至所有节点都输出,或当前图中不存在无前驱的节点(存在环)。

图采用邻接表实现,头文件代码如下:

#define  MAX_VERTEX_NUM 20

typedef 
int  InfoType;
typedef 
char  VertexType;

typedef 
enum   {DG, DN, UDG, UDN}  GraphKind;

typedef 
struct  ArcNode {
    
int adjvex;
    
struct ArcNode *next;
    InfoType info;
}
ArcNode;

typedef 
struct  VNode {
    
int in_degree;
    VertexType data;
    ArcNode 
*firstarc;
}
VNode, AdjList[MAX_VERTEX_NUM];

typedef 
struct   {
    AdjList vertex;
    
int vexnum, arcnum;
    GraphKind kind;
}
algraph;

源文件代码:

#include  " algraph_topo.h "

#include 
" stdio.h "
#include 
" stdlib.h "

void  createDN(algraph  & g) {}
void  createUDN(algraph  & g) {}
void  createUDG(algraph  & g) {}

// locate the name vertice's index
int  locate(algraph g,  char  name) {
    
for(int i = 0; i < g.vexnum; i++){
        
if(name == g.vertex[i].data){
            
return i;
        }

    }

    
return -1;
}


void  createDG(algraph  & g) {
    printf(
"input the number of vertex and arcs: ");
    scanf(
"%d %d"&g.vexnum, &g.arcnum);
    fflush(stdin);
    
    
int i = 0, j = 0, k = 0;
    
    printf(
"input the name of vertex: ");
    
    
for(i = 0; i < g.vexnum; i++){
        scanf(
"%c"&g.vertex[i].data);
        fflush(stdin);
        g.vertex[i].firstarc 
= NULL;
        g.vertex[i].in_degree 
= 0;
    }

    
    
//construct the adjacent list
    char v1, v2;
    
int w;
    ArcNode 
*p;

    printf(
"input the %d arcs v1 v2 and weight: ", g.arcnum);
    
for(k = 0; k < g.arcnum; k++){
        scanf(
"%c %c %d"&v1, &v2, &w);
        fflush(stdin);
        i 
= locate(g, v1);
        j 
= locate(g, v2);

        
//new a node
        p = (ArcNode *)malloc(sizeof(ArcNode));
        p
->adjvex = j;
        p
->info = w;
        p
->next = NULL;

        
//insert the node in the head of list
        if(!g.vertex[i].firstarc){
            g.vertex[i].firstarc 
= p;
        }
else{
            p
->next = g.vertex[i].firstarc;
            g.vertex[i].firstarc 
= p;
        }


        g.vertex[j].in_degree
++;
    }

}


// print the list
void  printGraph(algraph g) {
    
for(int i = 0; i < g.vexnum; i++){
        printf(
"%c's adjacent list is: ", g.vertex[i].data);
        ArcNode 
*= g.vertex[i].firstarc;
        
while(p){
            printf(
"%c(%d) ", g.vertex[p->adjvex].data, p->info);
            p 
= p->next;
        }

        printf(
" ");
    }

}


void  createGragh(algraph  & g) {
    
    printf(
"please input the type of graph: ");
    scanf(
"%d"&g.kind);
    
    
switch(g.kind){
    
case DG: 
        createDG(g);
        
//printGraph(g);
        break;
    
case DN: 
        createDN(g);
        
break;
    
case UDG: 
        createUDG(g);
        
break;
    
case UDN: 
        createUDN(g);
        
break;
    }

}


// ²éÕÒÏÂÒ»¸ö
int  findNext(algraph g) {
    
for(int i = 0; i < g.vexnum; i++){
        
if(g.vertex[i].in_degree == 0){
            
return i;
        }

    }

    
return -1;
}


// topo order
void  topoSort(algraph g) {
    printf(
"the topo sort of graph is: ");
    
for(int i = 0; i < g.vexnum; i++){
        
int index = findNext(g);
        
if(index > -1){
            printf(
"%c ", g.vertex[index].data);

            
//don't consider the vertice again
            g.vertex[index].in_degree = -1;
            
            ArcNode 
*= g.vertex[index].firstarc;
            
while(p){
                g.vertex[p
->adjvex].in_degree--;
                p 
= p->next;
            }

        }
else{
            
break;
        }

    }

    printf(
" ");
}


void  main() {
    algraph g;
    createGragh(g);
    topoSort(g);
}

程序的运行结果如下:

please input the type of graph:
0
input the number of vertex and arcs:
6   8
input the name of vertex:
a
b
c
d
e
f
input the 
8  arcs v1 v2 and weight:
a d 
1
a c 
1
a b 
1
c e 
1
c b 
1
d e 
1
f e 
1
f d 
1
the topo sort of graph 
is :
a       c       b       f       d       e
Press any key to 
continue

说明:

(1) 为了避免重复检测入度为0的顶点,可设置一个栈暂存所有入度为0的顶点,复杂度为O(n + e)。而在程序中采用的是

     // don't consider the vertice again
    g.vertex[index].in_degree  =   - 1 ;

来实现的。复杂度要高一些。

(2) 可以使用DFS,退出DFS函数的顺序即为逆向的拓扑有序序列。

(3)关键路径 

a. AOV网:用顶点表示活动,用弧表示活动间的优先关系的有向图称为顶点表示活动的网(activity on vertex network)。AOV网中,没有有向环。

b. AOE网:边表示活动的网络(顶点表示事件,弧表示活动),用来估算工程的完成时间,通常只有一个源点和一个汇点。

c. 求AOE算法的复杂度是O(n + e)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python是一种流行的编程语言,可以用来处理论问题。在Python中,可以使用数据结构来表示和操作有向无环图(Directed Acyclic Graph,DAG)。有向无环图是一种结构,其中的边都是有方向的,并且不存在任何形成环路的路径。 在Python中,可以使用各种论库来处理有向无环图,例如networkx、graph-tool等。这些库提供了一系列的函数和方法,可以用来创建、操作和分析有向无环图。 具体来说,要判断一个是否是有向无环图,可以使用拓扑排序算法。拓扑排序是一种对有向无环图进行排序的算法,它将中的节点按照依赖关系进行排序,使得每个节点在排列中都位于它的依赖节点之后。 在Python中,可以使用拓扑排序算法来判断一个是否是有向无环图。如果拓扑排序成功完成,并且没有环路存在,则可以确定该有向无环图。 下面是一个示例代码,演示了如何使用Python和networkx库来判断一个是否是有向无环图: ```python import networkx as nx # 创建一个有向无环图 G = nx.DiGraph() G.add_edges_from([(1, 2), (2, 3), (3, 4)]) # 判断是否是有向无环图 if nx.is_directed_acyclic_graph(G): print("该有向无环图") else: print("该不是有向无环图") ``` 在上面的示例中,我们首先使用networkx库创建了一个有向无环图G,然后使用`is_directed_acyclic_graph`函数判断该是否是有向无环图。如果返回结果为True,则说明该有向无环图,否则说明该不是有向无环图。 希望这个示例对你有所帮助。如果你需要更多关于有向无环图的信息,可以参考networkx库的文档或者其他相关资料。<span class="em">1</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值