演算法-有向圖及可達性

來源:互聯網
上載者:User

標籤:

圖是由頂點和邊串連而成,如果邊是沒有方向的是就是之前文章中說的無向圖,關於無向圖可以參考本人之前的文章,如果邊是有方向的,則稱之為有向圖。從頂點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<vertexs; i++) {            NSMutableArray  *neighbourVertex=[[NSMutableArray alloc]initWithCapacity:1];            [self.adjDataSource addObject:neighbourVertex];//建立鄰接表,將所有鏈表初始化為空白        }    }    return self;}//http://www.cnblogs.com/xiaofeixiang-(void)addEdges:(NSInteger)startVertex endVertex:(NSInteger)endVertex{    //將endVertex添加到startVertex的鏈表中    [self.adjDataSource[startVertex] insertObject:[NSNumber numberWithInteger:endVertex] atIndex:0];    self.edges=self.edges+1;}-(Digraph *)reverse{        Digraph  *digraph=[[Digraph alloc]initWithVertex:self.vertexs];    for (NSInteger i=0; i<self.vertexs; i++) {        NSMutableArray  *tempArr=self.adjDataSource[i];        for (NSInteger j=0; j<[tempArr count]; j++) {            [digraph addEdges:[tempArr[j] integerValue] endVertex:i];        }    }    return digraph;}#pragma mark getter and setter-(NSMutableArray *)adjDataSource{    if (!_adjDataSource) {        _adjDataSource=[[NSMutableArray alloc]initWithCapacity:1];    }    return _adjDataSource;}@end

測試代碼:

        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<graph.vertexs;i++) {            [self.marked addObject:[NSNull null]];        }        //遍曆有向圖中的頂點        for (NSInteger j=0; j<[arr count]; j++) {            if (![self isMarked:[arr[j] integerValue]]) {                [self directedDFS:graph vertex:[arr[j] integerValue]];            }        }    }    return self;}//部落格園-FlyElephant:http://www.cnblogs.com/xiaofeixiang/-(void)directedDFS:(Digraph *)graph vertex:(NSInteger)vertex{    self.marked[vertex]=[NSNumber numberWithBool:true];    for (NSInteger i=0; i<[graph.adjDataSource[vertex] count]; i++) {        NSInteger temp=[[graph.adjDataSource[vertex] objectAtIndex:i] integerValue];        if (![self isMarked:temp]) {            [self directedDFS:graph vertex:temp];        }    }}-(Boolean)isMarked:(NSInteger)vertex{    return self.marked[vertex]==[NSNull null]?false:[self.marked[vertex] boolValue];}@end

測試代碼:

        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<graph.vertexs; i++) {                        if (directedDFS.marked[i]&&directedDFS.marked[i]!=[NSNull null]) {                [reachableArr addObject:[NSNumber numberWithInteger:i]];            }        }        NSLog(@"可達的節點:%@",[reachableArr componentsJoinedByString:@"--"]);        NSLog(@"技術交流群:%@",@"228407086");        NSLog(@"部落格園-FlyElephant:http://www.cnblogs.com/xiaofeixiang");

測試效果:

 

演算法-有向圖及可達性

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.