博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法-无向图(深度优先搜索和广度优先搜索)
阅读量:6229 次
发布时间:2019-06-21

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

图中最常用到的两种搜索深度优先搜索和广度优先搜索,深度优先搜索是一种在开发爬虫早期使用较多的方法它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链接的Html文件) ,广度搜索属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

深度优先搜索

图中我们经常会遇到一个问题就是图的连通性,比如说从一个顶点到另外一个顶点,判断顶点和其他顶点之间的连通性,以下图为例:

搜索API定义:

@interface DepthFirstSearch : NSObject//记录顶点是否被标记@property  (strong,nonatomic)  NSMutableArray  *marked;@property (assign,nonatomic)  NSInteger count;//找到与七点vertex所有连通的节点-(instancetype)initWithGraphAndVertex:(Graph *)graph  vertex:(NSInteger)vertex;-(void)depthSearch:(Graph *)graph  vertex:(NSInteger)vertex;//节点是否被标记-(Boolean)isMarked:(NSInteger)vertex;@end

实现:

@implementation DepthFirstSearch#pragma mark  getter and setter-(NSMutableArray *)marked{    if (!_marked) {        _marked=[[NSMutableArray alloc]initWithCapacity:1];    }    return _marked;}-(instancetype)initWithGraphAndVertex:(Graph *)graph vertex:(NSInteger)vertex{    self=[super init];    if (self) {        for (NSInteger i=0; i

代码测试:

Graph  *graph=[[Graph alloc]initWithVertex:6];        [graph addEdges:0 endVertex:5];        [graph addEdges:2 endVertex:4];        [graph addEdges:2 endVertex:3];        [graph addEdges:1 endVertex:2];        [graph addEdges:0 endVertex:1];        [graph addEdges:3 endVertex:4];        [graph addEdges:5 endVertex:3];        [graph addEdges:0 endVertex:2];        DepthFirstSearch  *search=[[DepthFirstSearch alloc]initWithGraphAndVertex:graph vertex:0];        for (NSInteger i=0; i

测试效果:

1表示连通,节点0和其他节点直接都可以直接连通,我们通过递归的方式成功的判断亮点之间的连通性,顶点直接的连通性是通过边链接的,深度搜索将在此方法上改动然后给出单点之间的路径,注意是路径不是最短路径,我们会发现代码变动很小。

//深度优先@interface DepthFirstPath : NSObject//记录顶点是否被标记@property  (strong,nonatomic)  NSMutableArray  *marked;//起点@property (assign,nonatomic)  NSInteger  beginVertex;//从起点到一个顶点的已知路径上的最后一个顶点@property  (strong,nonatomic)  NSMutableArray *edgeTo;@property (assign,nonatomic)  NSInteger count;//找到与七点vertex所有连通的节点-(instancetype)initWithGraphAndVertex:(Graph *)graph  vertex:(NSInteger)vertex;-(void)depthSearch:(Graph *)graph  vertex:(NSInteger)vertex;-(NSMutableArray *)pathTo:(NSInteger)vertex;//节点是否被标记-(Boolean)hasPathTo:(NSInteger)vertex;@end

实现代码:

@implementation DepthFirstPath#pragma mark  getter and setter-(NSMutableArray *)marked{    if (!_marked) {        _marked=[[NSMutableArray alloc]initWithCapacity:1];    }    return _marked;}-(NSMutableArray *)edgeTo{    if (!_edgeTo) {        _edgeTo=[[NSMutableArray alloc]initWithCapacity:1];    }    return _edgeTo;}-(instancetype)initWithGraphAndVertex:(Graph *)graph vertex:(NSInteger)vertex{    self=[super init];    if (self) {        for (NSInteger i=0; i

代码中我们多了一个edgeTo数组记录当前索引顶点的最后一个顶点,当edgeTo[1]=2表示顶点1和顶点2之间是直接相连,最后输出路径的时候利用栈的特性,先进后出,输出正确路径,测试代码如下:

NSInteger  beginVertex=0;        DepthFirstPath *path=[[DepthFirstPath alloc]initWithGraphAndVertex:graph vertex:beginVertex];        for (NSInteger i=0; i<[path.edgeTo count]; i++) {            NSLog(@"节点%ld--值为:%@",i,path.edgeTo[i]);        }        for (NSInteger i=0; i

测试效果:

 

广度优先搜索

如果我们仔细观察会发现一个现象,图片中我们很明显看到顶点0可以直接到5,我们确发现广度搜索的路径给出的是0-2-3-5,如果想要获取最短路径,界限来一起看一下广度优先搜索,代码与上面的代码也是改动了一部分,比较好懂,代码如下:

@interface BreadthFirstPath : NSObject//记录顶点是否被标记@property  (strong,nonatomic)  NSMutableArray  *marked;//起点@property (assign,nonatomic)  NSInteger  beginVertex;//从起点到一个顶点的已知路径上的最后一个顶点@property  (strong,nonatomic)  NSMutableArray *edgeTo;//找到与七点vertex所有连通的节点-(instancetype)initWithGraphAndVertex:(Graph *)graph  vertex:(NSInteger)vertex;-(void)breadthSearch:(Graph *)graph  vertex:(NSInteger)vertex;-(NSMutableArray *)pathTo:(NSInteger)vertex;//节点是否被标记-(Boolean)hasPathTo:(NSInteger)vertex;@end

实现代码:

@implementation BreadthFirstPath#pragma mark  getter and setter-(NSMutableArray *)marked{    if (!_marked) {        _marked=[[NSMutableArray alloc]initWithCapacity:1];    }    return _marked;}-(NSMutableArray *)edgeTo{    if (!_edgeTo) {        _edgeTo=[[NSMutableArray alloc]initWithCapacity:1];    }    return _edgeTo;}-(instancetype)initWithGraphAndVertex:(Graph *)graph vertex:(NSInteger)vertex{    self=[super init];    if (self) {        for (NSInteger i=0; i
0) { NSInteger header=[[queue objectAtIndex:0] integerValue]; [queue removeObjectAtIndex:0]; for (NSInteger i=0; i<[graph.adjDataSource[header] count]; i++) { NSInteger temp=[[graph.adjDataSource[header] objectAtIndex:i] integerValue]; if (![self isMarked:temp]) { self.marked[temp]=[NSNumber numberWithBool:true]; self.edgeTo[temp]=[NSNumber numberWithInteger:header]; [queue addObject:[NSNumber numberWithInteger:temp]]; } } }}-(Boolean)isMarked:(NSInteger)vertex{ return self.marked[vertex]==[NSNull null]?false:[self.marked[vertex] boolValue];}-(Boolean)hasPathTo:(NSInteger)vertex{ return self.marked[vertex]==[NSNull null]?false:[self.marked[vertex] boolValue];}-(NSMutableArray *)pathTo:(NSInteger)vertex{ if (![self hasPathTo:vertex]) { return NULL; } NSMutableArray *path=[[NSMutableArray alloc]initWithCapacity:1]; for (NSInteger i=vertex; i!=self.beginVertex; i=[self.edgeTo[i] integerValue]) { [path insertObject:[NSNumber numberWithInteger:i] atIndex:0]; } [path insertObject:[NSNumber numberWithInteger:self.beginVertex] atIndex:0]; return path;}@end

测试代码:

NSInteger  beginVertex=0;        BreadthFirstPath  *breadthPath=[[BreadthFirstPath alloc]initWithGraphAndVertex:graph vertex:beginVertex];        for (NSInteger i=0; i<[breadthPath.edgeTo count]; i++) {            NSLog(@"节点%ld--值为:%@",i,breadthPath.edgeTo[i]);        }        for (NSInteger i=0; i

测试效果:

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

你可能感兴趣的文章
「题单」网络流『费用流』
查看>>
红黑树 C++实现
查看>>
root登录不进去 dropbear ssh
查看>>
AC自动机跟随Kuangbing学习笔记
查看>>
[20190507]sga_target=0注意修改_kghdsidx_count设置.txt
查看>>
laya的skeleton骨骼动画事件响应问题
查看>>
oracle wm_concat 拼接乱码 显示问号等
查看>>
LightOJ 1027 Dangerous Maze
查看>>
hive --桶
查看>>
event 实现两个程序的交互
查看>>
gulp之压缩css,less转css,浏览器实时刷新【原创】
查看>>
[转] mysql分区性能初探
查看>>
1.6给定一个由N*N矩阵表示的图像,其中每个像素的大小为4字节,编写一份方法,将图像旋转90度。不占用额外内存空间能否做到?...
查看>>
Python 使用有道翻译
查看>>
python django day 5 database 1
查看>>
A2dp sink 初始化流程源码分析
查看>>
使用外部配置文件
查看>>
【原】小搞一下 javascript算法
查看>>
Undefined symbols for architecture x86_64 "_OBJC_CLASS_$_类名",referenced fromobjc-class in .o
查看>>
vi保存文件
查看>>