邻接列表并使用深度优先搜索

时间:2016-06-03 11:37:08

标签: ios objective-c depth-first-search

这是连接看台的双向图

 STAND_ID_FK    CONNECTED_STAND DISTANCE_BETWEEN_STAND  TIME_BETWEEN_STAND
    101              102              1                      2
    102              103            0.8                    1.5
    103              104            1.4                      2 
    104              105            1.007                    2
    105              106            1.264                    2
    106              107            0.8                    1.5

我想创建一个最适合图表表示的邻接列表或列表。我很困惑,我可以通过NSMutableArray做到这一点,如果是,那么如何?然后我必须在图表中暗示dfs来遍历列表中从任何给定源到目标的最短路径,如102到106或108到103

1 个答案:

答案 0 :(得分:1)

您可以在线找到更好的资源,但这是Objective-C中Graph,Vertex和DFS的基本实现:

<强> Graph.h

@interface Graph : NSObject

-(instancetype)initWithVertex:(Vertex*)vertex;
-(void)addVertexFrom:(Vertex*)fromVertex toVertex:(Vertex*)toVertex;
-(void)printAdjacencyList;
-(void)bfs:(Vertex*)root;
-(void)dfs:(Vertex*)root;

@end

<强> Graph.m

@interface Graph()

@property(nonatomic, strong) NSMutableDictionary<Vertex*, NSMutableArray<Vertex*>*> *adjacencyList;

@end

@implementation Graph

-(instancetype)initWithVertex:(Vertex*)vertex
{
    if (self = [super init])
    {
        self.adjacencyList = [NSMutableDictionary new];
        [self addVertexFrom:vertex toVertex:nil];
    }

    return self;
}

-(void)addVertexFrom:(Vertex*)fromVertex toVertex:(Vertex*)toVertex
{
    Vertex *fromV = [self isVertexPresent:fromVertex];

    if (fromV)
    {
        NSMutableArray *adjacentVertices = _adjacencyList[fromV];
        [adjacentVertices addObject:toVertex];
    }
    else
    {
        [_adjacencyList setObject:toVertex ? [NSMutableArray arrayWithObject:toVertex] : [NSMutableArray new] forKey:fromVertex];
    }
}

-(Vertex*)isVertexPresent:(Vertex*)vertex
{
    for (Vertex *v in _adjacencyList.allKeys)
    {
        if ([v isEqual:vertex])
        {
            return v;
        }
    }

    return nil;
}

-(void)printAdjacencyList
{
    NSMutableString *graphDesciption = [[NSMutableString alloc] init];

    for (Vertex *v in _adjacencyList.allKeys)
    {
        [graphDesciption appendString:[NSString stringWithFormat:@"\n%@ -> ", v.data]];

        for (Vertex *adjV in _adjacencyList[v])
        {
            [graphDesciption appendString:[NSString stringWithFormat:@"%@, ", adjV.data]];
        }

        [graphDesciption appendString:@"\n"];
    }

    NSLog(@"%@", graphDesciption);
}

-(void)bfs:(Vertex*)root
{
    NSMutableArray *queue = [NSMutableArray new];
    [queue addObject:root];

    while (queue.count)
    {
        Vertex *curr = [queue objectAtIndex:0];
        [queue removeObjectAtIndex:0];

        if (curr.state != Visited)
        {
            curr.state = Visited;
            NSLog(@"\n%ld", (long)curr.data.integerValue);
            NSArray *temp = _adjacencyList[curr];
            for (Vertex *v in temp)
            {
                [queue addObject:v];
            }
        }
    }
}

-(void)dfs:(Vertex*)root
{
    if (root == nil) return;

    NSLog(@"\n%ld", (long)root.data.integerValue);
    root.state = Visited;

    for (Vertex *v in _adjacencyList[root])
    {
        if (v.state != Visited)
        {
            [self dfs:v];
        }
    }
}

@end

以下是如何在 main.m 中使用它的示例:

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        Vertex *vertex0 = [[Vertex alloc] initWithIndex:@(0) data:@(0)];
        Vertex *vertex1 = [[Vertex alloc] initWithIndex:@(1) data:@(1)];
        Vertex *vertex2 = [[Vertex alloc] initWithIndex:@(2) data:@(2)];
        Vertex *vertex3 = [[Vertex alloc] initWithIndex:@(3) data:@(3)];
        Vertex *vertex4 = [[Vertex alloc] initWithIndex:@(4) data:@(4)];
        Vertex *vertex5 = [[Vertex alloc] initWithIndex:@(5) data:@(5)];

        Graph *graph = [[Graph alloc] initWithVertex:vertex0];

        [graph addVertexFrom:vertex0 toVertex:vertex1];
        [graph addVertexFrom:vertex0 toVertex:vertex4];
        [graph addVertexFrom:vertex0 toVertex:vertex5];

        [graph addVertexFrom:vertex1 toVertex:vertex3];
        [graph addVertexFrom:vertex1 toVertex:vertex4];

        [graph addVertexFrom:vertex2 toVertex:vertex1];

        [graph addVertexFrom:vertex3 toVertex:vertex2];
        [graph addVertexFrom:vertex3 toVertex:vertex4];

        [graph dfs:vertex0];

        return 0;
    }
}

就像我说的那样,您可以轻松创建自己的解决方案,因为Graphs上有大量的材料。我只给出了一种方法。