iOS二叉树

#import <Foundation/Foundation.h>

@interface BinaryTreeNode : NSObject

///值
@property (nonatomic, assign) NSInteger value;
///左节点
@property (nonatomic, strong) BinaryTreeNode *leftNode;
///右节点
@property (nonatomic, strong) BinaryTreeNode *rightNode;

/// 便利构造器
+ (instancetype)nodeWithValue:(NSInteger)value;

@end
#import "BinaryTreeNode.h"

@implementation BinaryTreeNode


+ (instancetype)nodeWithValue:(NSInteger)value{
    BinaryTreeNode *node = [[super alloc]init];
    node.value = value;
    return  node;
}

@end


//  二叉树一些方法

/**************************使用测试*****************************
 NSArray *arr = @[@4,@2,@7,@1,@3,@6,@9];
 BinaryTreeNode *node = [BinaryTree createTreeWithValues:arr];
 NSLog(@"%@",node);
 BinaryTreeNode *overNode = [BinaryTree invertBinaryTree:node];
 NSLog(@"%@",overNode);
 **************************************************************/

#import <Foundation/Foundation.h>

@class BinaryTreeNode;

@interface BinaryTree : NSObject
///创建二叉树
+ (BinaryTreeNode *)createTreeWithValues:(NSArray *)values;

/// 反转二叉树
+ (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode;

/// 反转二叉树(非递归)
+ (BinaryTreeNode *)invertBinaryTreeWithoutRecursion:(BinaryTreeNode *)rootNode;

/// 二叉树深度
+ (NSInteger)depathOfTree:(BinaryTreeNode *)rootNode;

/// 二叉树所有节点数  节点数=左子树节点数+右子树节点数+1(根节点)
+ (NSInteger)numberOfNodesInTree:(BinaryTreeNode *)rootNode;

//二叉树中某个节点到根节点的路径
+ (NSArray *)pathOfTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode;

/// 先序遍历
//http://baike.baidu.com/link?url=rODMnACQtOHoi2j-w8riDGKfT1exqmaD9aMo1Mq9ECAZWnEuSr3oI3MAH5i2tLBx6GjYCCfMpELgiXMaXQFW5_
+ (void)treeFirstInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block;

/// 中序遍历
//http://baike.baidu.com/link?url=98LrnOmbH7lUzt-kde2L4-aRuISGpg0he4XOiEl3OxqO9tzwL8oGFOrIdiQP4s_DmLAk3woPAaMAbOBO2qQ9Va
+ (void)treeMiddleInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block;

/// 后序遍历
//http://baike.baidu.com/link?url=jbHRJx477WlWPGA52RhiY3yo2HTjE087QFDNrV7E9dyhES7ftDZ3SdcJZFL4dv4UuXDelpdgdqysjE5y02aICa
+ (void)treeLastInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger value))block;
@end

#import "BinaryTree.h"
#import "BinaryTreeNode.h"

@implementation BinaryTree


/**
 生成二叉树

 @param values 数组
 @return 二叉树
 */
+ (BinaryTreeNode *)createTreeWithValues:(NSArray *)values
{
    BinaryTreeNode *root = nil;
    
    for (NSInteger i=0; i<values.count; i++) {
        NSInteger value = [(NSNumber *)[values objectAtIndex:i]integerValue];
        root = [[self class]addTreeNode:root value:value];
    }
    
    return root;
}


/**
 翻转二叉树(非递归)

 @param rootNode 根节点
 @return 翻转后的树根节点(其实就是原二叉树的根节点)
 */
+ (BinaryTreeNode *)invertBinaryTreeWithoutRecursion:(BinaryTreeNode *)rootNode
{
    if (!rootNode) {  return nil; }
    if (!rootNode.leftNode && !rootNode.rightNode) {  return rootNode; }
    NSMutableArray *queueArray = [NSMutableArray array]; //数组当成队列
    [queueArray addObject:rootNode]; //压入根节点
    while (queueArray.count > 0) {
        BinaryTreeNode *node = [queueArray firstObject];
        [queueArray removeObjectAtIndex:0]; //弹出最前面的节点,仿照队列先进先出原则
        BinaryTreeNode *pLeft = node.leftNode;
        node.leftNode = node.rightNode;
        node.rightNode = pLeft;
        
        if (node.leftNode) {
            [queueArray addObject:node.leftNode];
        }
        if (node.rightNode) {
            [queueArray addObject:node.rightNode];
        }
    }
    return rootNode;
}

/**
 * 翻转二叉树(又叫:二叉树的镜像)
 *
 * @param rootNode 根节点
 *
 * @return 翻转后的树根节点(其实就是原二叉树的根节点)
 */
+ (BinaryTreeNode *)invertBinaryTree:(BinaryTreeNode *)rootNode
{
    if (!rootNode) {  return nil; }
    if (!rootNode.leftNode && !rootNode.rightNode) {  return rootNode; }
    [self invertBinaryTree:rootNode.leftNode];
    [self invertBinaryTree:rootNode.rightNode];
    BinaryTreeNode *tempNode = rootNode.leftNode;
    rootNode.leftNode = rootNode.rightNode;
    rootNode.rightNode = tempNode;
    return rootNode;
}

#pragma mark - 遍历二叉树
/// 先序遍历
+ (void)treeFirstInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger))block
{
    if (block) {
        block(rootNode.value);
    }
    if (rootNode.leftNode) {
        [self treeFirstInformationWithNode:rootNode.leftNode resultBlock:block];
    }
    if (rootNode.rightNode) {
        [self treeFirstInformationWithNode:rootNode.rightNode resultBlock:block];
    }
}

/// 中遍历
+ (void)treeMiddleInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger))block
{
    if (rootNode.leftNode) {
        [self treeMiddleInformationWithNode:rootNode.leftNode resultBlock:block];
    }
    if (block) {
        block(rootNode.value);
    }
    if (rootNode.rightNode) {
        [self treeMiddleInformationWithNode:rootNode.rightNode resultBlock:block];
    }
    
}
/// 后遍历
+ (void)treeLastInformationWithNode:(BinaryTreeNode *)rootNode resultBlock:(void (^)(NSInteger))block{
    if (rootNode.leftNode) {
        [self treeLastInformationWithNode:rootNode.leftNode resultBlock:block];
    }
    if (rootNode.rightNode) {
        [self treeLastInformationWithNode:rootNode.rightNode resultBlock:block];
    }
    
    if (block) {
        block(rootNode.value);
    }
}

+ (NSInteger)depathOfTree:(BinaryTreeNode *)rootNode
{
    if (!rootNode) return 0;
    if (!rootNode.leftNode && rootNode.rightNode) return 1;
    NSInteger leftDepth = [self depathOfTree:rootNode.leftNode];
    NSInteger rightDepth = [self depathOfTree:rootNode.rightNode];
    
    return  MAX(leftDepth, rightDepth)+1;
}

+ (NSInteger)numberOfNodesInTree:(BinaryTreeNode *)rootNode
{
    if(!rootNode) return 0;
    return [self numberOfNodesInTree:rootNode.leftNode]+[self numberOfNodesInTree:rootNode]+1;
}

+ (NSArray *)pathOfTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode
{
    NSMutableArray *pathArray = [NSMutableArray array];
    [self isFoundTreeNode:treeNode inTree:rootNode routePath:pathArray];
    return  pathArray;
}


#pragma mark - Private
+ (BinaryTreeNode *)addTreeNode:(BinaryTreeNode *)treeNode value:(NSInteger)value
{
    if (!treeNode) { //根节点不惨在,创建节点
        treeNode = [BinaryTreeNode new];
        treeNode.value = value;
    }else if (value <= treeNode.value){
        treeNode.leftNode = [[self class]addTreeNode:treeNode value:value];
    }else{
        treeNode.rightNode = [[self class]addTreeNode:treeNode value:value];
    }
    return treeNode;
}


+ (BOOL)isFoundTreeNode:(BinaryTreeNode *)treeNode inTree:(BinaryTreeNode *)rootNode routePath:(NSMutableArray *)path {
    
    if (!rootNode || !treeNode) {
        return NO;
    }
    //找到节点
    if (rootNode == treeNode) {
        [path addObject:rootNode];
        return YES;
    }
    //压入根节点,进行递归
    [path addObject:rootNode];
    //先从左子树中查找
    BOOL find = [self isFoundTreeNode:treeNode inTree:rootNode.leftNode routePath:path];
    //未找到,再从右子树查找
    if (!find) {
        find = [self isFoundTreeNode:treeNode inTree:rootNode.rightNode routePath:path];
    }
    //如果2边都没查找到,则弹出此根节点
    if (!find) {
        [path removeLastObject];
    }
    
    return find;
}

@end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值