#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