#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
iOS二叉树
最新推荐文章于 2021-06-18 14:56:21 发布