OC实现前序遍历、中序遍历、后序遍历还原二叉树

1、概念

  1. 前序遍历:a、访问根节点 b、访问左节点 c、访问右节点
  2. 中序遍历:a、访问左节点 b、访问根节点 c、访问右节点
  3. 后序遍历:a、访问左节点 b、访问右节点 c、访问根节点

 

2、已知前序遍历、中序遍历还原二叉树

思想: 前序遍历的第一个元素是根结点,然后根据根结点在中序遍历中的位置将二叉树分成左子树和右子树,然后递归左右子树,继续上面的查找根结点,拆分左右子树,直至为nil

具体代码:

@interface TNode : NSObject

@property (nonatomic, assign) NSInteger value;

@property (nonatomic, strong) TNode *leftNode;

@property (nonatomic, strong) TNode *rightNode;

@end

 

@implementation TNode

@end

 

// 根据前序遍历和中序遍历获取二叉树

void getNodeWithPreAndMin(TNode **rootNode, NSArray *arrayPre, NSArray *arrayMin) {

    if ((arrayPre.count == 0) && (arrayMin.count == 0)) {

        return;

    }

    

    NSNumber *root = arrayPre.firstObject;  // 获取根结点

    

    TNode *node = [[TNode alloc] init];

    *rootNode = node;

    

    node.value = [root integerValue];

    

    __block NSInteger rootIndex = 0;    // 根结点在中序遍历中的位置

    [arrayMin enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

        if ([obj integerValue] == [root integerValue]) {

            rootIndex = idx;

            *stop = YES;

        }

    }];

    

    // 左树枝处理

    NSArray *arrayLeftPre = [arrayPre subarrayWithRange:NSMakeRange(1, rootIndex)];

    NSArray *arrayLeftMin = [arrayMin subarrayWithRange:NSMakeRange(0, rootIndex)];

    

    TNode *leftNode = nil;

    getNodeWithPreAndMin(&leftNode, arrayLeftPre, arrayLeftMin);

    

    node.leftNode = leftNode;

    

    // 右树枝处理

    NSArray *arrayRightPre = [arrayPre subarrayWithRange:NSMakeRange(rootIndex + 1, arrayPre.count - rootIndex - 1)];

    NSArray *arrayRightMin = [arrayMin subarrayWithRange:NSMakeRange(rootIndex + 1, arrayMin.count - rootIndex - 1)];

    

    TNode *rightNode = nil;

    getNodeWithPreAndMin(&rightNode, arrayRightPre, arrayRightMin);

    

    node.rightNode = rightNode;

}

 

// 打印前序遍历

void printNodePre(TNode *node) {

    if (node) {

        NSLog(@"%ld", node.value);

        printNodePre(node.leftNode);

        printNodePre(node.rightNode);

    }

}

 

// 打印中序遍历

void printNodeMin(TNode *node) {

    if (node) {

        printNodeMin(node.leftNode);

        NSLog(@"%ld", node.value);

        printNodeMin(node.rightNode);

    }

}

 

// 打印后序遍历

void printNodeLater(TNode *node) {

    if (node) {

        printNodeLater(node.leftNode);

        printNodeLater(node.rightNode);

        NSLog(@"%ld", node.value);

    }

}

 

例如:

NSArray *arrayPre = @[ @(1), @(2), @(4), @(7), @(3), @(5), @(6), @(8) ];

NSArray *arrayMin = @[ @(4), @(7), @(2), @(1), @(5), @(3), @(8), @(6) ];

TNode *rootNode = nil;

getNodeWithPreAndMin(&rootNode, arrayPre, arrayMin);

 

NSLog(@"前序遍历");

printNodePre(rootNode);

        

NSLog(@"中序遍历");

printNodeMin(rootNode);

        

NSLog(@"后序遍历");

printNodeLater(rootNode);

3、已知中序遍历、后序遍历还原二叉树

思想:同上,后序遍历的最后一个元素是根结点,然后根据根结点在中序遍历中的位置将二叉树分成左子树和右子树,然后递归左右子树,继续上面的查找根结点,拆分左右子树,直至为nil

具体代码:

// 根据中序遍历和后序遍历获取二叉树

void getNodeWithMinAndLater(TNode **rootNode, NSArray *arrayMin, NSArray *arrayLater) {

    if ((arrayMin.count == 0) && (arrayLater.count == 0)) {

        return;

    }

    

    NSNumber *root = arrayLater.lastObject;  // 获取根结点

    

    TNode *node = [[TNode alloc] init];

    *rootNode = node;

    

    node.value = [root integerValue];

    

    __block NSInteger rootIndex = 0;    // 根结点在中序遍历中的位置

    [arrayMin enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

        if ([obj integerValue] == [root integerValue]) {

            rootIndex = idx;

            *stop = YES;

        }

    }];

    

    // 左树枝处理

    NSArray *arrayLeftMin = [arrayMin subarrayWithRange:NSMakeRange(0, rootIndex)];

    NSArray *arrayLeftLater = [arrayLater subarrayWithRange:NSMakeRange(0, rootIndex)];

    

    TNode *leftNode = nil;

    getNodeWithMinAndLater(&leftNode, arrayLeftMin, arrayLeftLater);

    

    node.leftNode = leftNode;

    

    // 右树枝处理

    NSArray *arrayRightMin = [arrayMin subarrayWithRange:NSMakeRange(rootIndex + 1, arrayMin.count - rootIndex - 1)];

    NSArray *arrayRightLater = [arrayLater subarrayWithRange:NSMakeRange(rootIndex, arrayLater.count - rootIndex - 1)];

    

    TNode *rightNode = nil;

    getNodeWithMinAndLater(&rightNode, arrayRightMin, arrayRightLater);

    

    node.rightNode = rightNode;

}

注:只有前序遍历和后序遍历无法确定二叉树。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值