博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法-有向图及可达性
阅读量:5994 次
发布时间:2019-06-20

本文共 3490 字,大约阅读时间需要 11 分钟。

图是由顶点和边连接而成,如果边是没有方向的是就是之前文章中说的无向图,关于无向图可以参考本人之前的文章,如果边是有方向的,则称之为有向图。从顶点A→B,我们可以理解为A到B可达,有向图和无向图一样通过邻接表保存每一条边,由于边是有方向的,因此在添加边的过程中只需要添加一条边即可。关于可达性一个节点数组的可达性,采用的方法是之前的深度优先搜索一样的代码,通过递归将标记位Bool标记位判断数组中每个顶点的可达性。为了测试,选择下面一张有向图:

有向图基础

通过图片我们可以发现图中有13个节点,22条边,顶点0指出的节点有1,5,指入的节点有2,6,我们先实现所有顶点指出的节点,之后可以通过反转判断所有节点的指入节点:

@interface Digraph : NSObject//顶点的总数@property  (assign,nonatomic) NSInteger  vertexs;//边的数总数@property (assign,nonatomic) NSInteger  edges;//连接点的边@property (strong,nonatomic)  NSMutableArray  *adjDataSource;-(instancetype)initWithVertex:(NSInteger)vertexs;//添加一条有向边 startVertex→endVertex-(void)addEdges:(NSInteger)startVertex  endVertex:(NSInteger)endVertex;-(Digraph *)reverse;//该图的反向图@end

实现代码:

@implementation Digraph-(instancetype)initWithVertex:(NSInteger)vertexs{    self=[super init];    if (self) {        self.vertexs=vertexs;        for (NSInteger i=0; i

测试代码:

Digraph  *graph=[[Digraph alloc]initWithVertex:13];        [graph addEdges:4 endVertex:2];        [graph addEdges:2 endVertex:3];        [graph addEdges:3 endVertex:2];        [graph addEdges:6 endVertex:0];        [graph addEdges:0 endVertex:1];        [graph addEdges:2 endVertex:0];        [graph addEdges:11 endVertex:12];        [graph addEdges:12 endVertex:9];        [graph addEdges:9 endVertex:10];        [graph addEdges:9 endVertex:11];        [graph addEdges:8 endVertex:9];        [graph addEdges:10 endVertex:12];        [graph addEdges:11 endVertex:4];        [graph addEdges:4 endVertex:3];        [graph addEdges:3 endVertex:5];        [graph addEdges:7 endVertex:8];        [graph addEdges:8 endVertex:7];        [graph addEdges:5 endVertex:4];        [graph addEdges:0 endVertex:5];        [graph addEdges:6 endVertex:4];        [graph addEdges:6 endVertex:9];        [graph addEdges:7 endVertex:6];        for (NSInteger i=0; i<[graph.adjDataSource count]; i++) {            NSLog(@"节点%ld指出→的节点:%@",i,[graph.adjDataSource[i] componentsJoinedByString:@"--"]);        }        NSLog(@"技术交流群:%@",@"228407086");        NSLog(@"原文地址:http://www.cnblogs.com/xiaofeixiang");

测试效果:

现在可以判断出顶点的指出节点,实现文件中有一个reverse方法将图反转,求出顶点的转入节点:

Digraph  *digraph=[graph reverse];        for (NSInteger i=0; i<[digraph.adjDataSource count]; i++) {            NSLog(@"指入%ld⬅️的节点:%@",i,[digraph.adjDataSource[i] componentsJoinedByString:@"--"]);        }        NSLog(@"技术交流群:%@",@"228407086");        NSLog(@"原文地址:http://www.cnblogs.com/xiaofeixiang");

测试效果:

可达性

可达性的判断和之前的深度优先搜索基本没变化,先来看一下需要实现的方法:

@interface DirectedDFS : NSObject//标记数组@property  (strong,nonatomic)  NSMutableArray  *marked;//找到arr中顶点可达的所有顶点-(instancetype)initDirectedDFSWithVertex:(Digraph *)graph  vertexArr:(NSArray *)arr;//在graph中找到从vertex可达的所有顶点-(void)directedDFS:(Digraph *)graph  vertex:(NSInteger)vertex;//vertex是否可达-(Boolean)isMarked:(NSInteger)vertex;@end

实现代码:

@implementation DirectedDFS#pragma mark  getter and setter-(NSMutableArray *)marked{    if (!_marked) {        _marked=[[NSMutableArray alloc]initWithCapacity:1];    }    return _marked;}-(instancetype)initDirectedDFSWithVertex:(Digraph *)graph vertexArr:(NSArray *)arr{    self=[super init];    if (self) {        for (NSInteger i=0; i

测试代码:

NSArray  *sources=[NSArray arrayWithObjects:@"2", nil];        DirectedDFS  *directedDFS=[[DirectedDFS alloc]initDirectedDFSWithVertex:graph vertexArr:sources];        NSMutableArray  *reachableArr=[[NSMutableArray alloc]initWithCapacity:1];        for (NSInteger i=0; i

测试效果:

 

转载于:https://www.cnblogs.com/xiaofeixiang/p/4703980.html

你可能感兴趣的文章
如何提高Java并行程序性能
查看>>
数据加密到底管不管用
查看>>
面向对象程序与类
查看>>
安装vsftpd
查看>>
Linux性能分析的前60000毫秒
查看>>
Power of Three(leetcode326)
查看>>
网络安全与安全体系的建立
查看>>
Nginx之虚拟目录-root与alias的区别
查看>>
关于MySQL二进制日志Binlog的认识
查看>>
×××LAMP+FastCGI+xcache加速器
查看>>
华为交换机通用配置方法
查看>>
lduan server 2012 系统批量激活(三十二)
查看>>
自定义key解决zabbix端口监听取值不准确的问题
查看>>
我的友情链接
查看>>
java --枚举
查看>>
Linux 操作命令 df
查看>>
JS判断坐标点是否在给定的多边形内
查看>>
21.这个看起来有点简单
查看>>
C++重载运算符
查看>>
Spring的理解
查看>>