在Objective-C中遍历从root到树的所有子项

时间:2015-05-17 19:04:51

标签: objective-c recursion path tree

我想要做的简化版本就是这样翻译一棵树:
sample tree
进入这样的数组:[“abc”,“abd”,“ae”]

基本上我想将树从它的根节点遍历到每个子节点。

我尝试通过在递归块中放入一个for-in循环来做到这一点,但问题是for循环会在每次递归块时重新开始。当我尝试异步运行块时,我不断获得EXC_BAD_ACCESS

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

假设树的表示如下:

@interface TreeNode : NSObject
@property(weak,nonatomic) TreeNode *parent;
@property(strong,nonatomic) NSArray *children;
@end

任何节点的沿袭(这是您正在寻找的)是从根到节点的节点列表。这可以像这样递归定义:

- (NSArray *)lineage {
    if (!self.parent) {
        return @[self];
    } else {
        NSMutableArray *lineage = [[self.parent lineage] mutableCopy];
        [lineage addObject:self];
        return lineage;
    }
}

你正在寻找叶子的血统,所以我们需要一种收集叶子的方法。如果我们可以遍历树,我们就可以做到这一点。这是一个很好的块应用程序,如下所示:

- (void)depthFirst:(void (^)(TreeNode *))block {
    for (TreeNode *node in self.children) {
        [node depthFirst:block];
    }
    return block(self);
}

这提供了收集树叶的自然方式:

- (NSArray *)leaves {
    NSMutableArray *leaves = [@[] mutableCopy];
    [self depthFirst:^(TreeNode *node) {
        if (!node.children) [leaves addObject:node];
    }];
    return leaves;
}

把它放在一起,我们得到:

- (NSArray *)lineagesOfLeaves {
    NSMutableArray lineages = [@[] mutableCopy];
    for (TreeNode *leaf in [self leaves]) {
        [lineages addObject:[leaf lineage]];
    }
    return lineages;
}

这些方法适用于树中的任何节点。但是,对于您的问题,您希望将lineagesOfLeaves发送到树的根目录。