给定一个二叉树,找出所有路径中各节点相加总和。 一个有效的路径,指的是从根节点到叶节点的路径。这样就是一条有效的路径,求这个路径上值的和,以及对应路径上的值.
当用前序遍历的方式访问到某一结点时,我们把该结点添加到路径(数组或栈中)上,并累加该结点的值。 如果该结点为叶结点,路径结束,我们把它打印出来。 如果当前结点不是叶结点,则继续访问它的子结点。 当前结点访问结束后,递归函数将自动回到它的父结点。因此我们在函数退出之前要在路径上删除当前结点并减去当前结点的值,以确保返回父结点时路径刚好是从根结点到父结点的路径。由此可以看出保存路径的数据结构实际上是一个栈,因为路径要与递归调用状态一致,而递归调用的本质就是一个压栈和出栈的过程。
好,下面到代码部分.
二叉树的节点定义, 根据传入数组,生成对应的完全二叉树
@interface TreeNode : NSObject /// 根据数组生成一个完全二叉树 + (TreeNode *)nodeWithDataArray:(NSArray *)dataArray; /// 生成一个节点,左右节点为nil + (TreeNode *)nodeWithData:(int)data; /// 生成一个节点,左右节点为指定节点 + (TreeNode *)nodeWithData:(int)data leftNode:(TreeNode *)leftNode rightNode:(TreeNode *)rightNode; @property (nonatomic, assign) int data; @property (nonatomic, strong) TreeNode * leftNode; @property (nonatomic, strong) TreeNode * rightNode; @end ------- #import "TreeNode.h" @implementation TreeNode // 实现方式1:根据完全二叉树的下标(1~n)来处理, 任意子节点的下标/2 都是父节点 + (TreeNode *)nodeWithDataArray:(NSArray *)dataArray { if (dataArray == nil || dataArray.count == 0) { return nil; } //根据数组的数量,生成一个完全二叉树 NSMutableArray<TreeNode *> * treeArray = [NSMutableArray array]; //放一个占位的值,这样根节点的下标就对应成treeArray[1]了,计算父节点会更容易点 [treeArray addObject:[TreeNode nodeWithData:NAN]]; for (int i = 0; i<dataArray.count; i++) { NSNumber * num = dataArray[i]; TreeNode * temp = [TreeNode nodeWithData:num.intValue]; // 如果是偶数,说明是对应父节点的左子节点 if (treeArray.count%2==0&&treeArray.count>1) { TreeNode * father = treeArray[treeArray.count/2]; father.leftNode = temp; } // 如果是奇数,说明是对应父节点的右子节点 if (treeArray.count%2==1) { TreeNode * father = treeArray[treeArray.count/2]; father.rightNode = temp; } [treeArray addObject:temp]; } return treeArray[1]; } /// 实现方式2:模拟层次遍历, 依次生成子节点并赋值 + (TreeNode *)nodeWithDataArray2:(NSArray<NSNumber *> *)dataArray { if (dataArray == nil || dataArray.count == 0) { return nil; } //模拟队列结构,进行层次遍历 NSMutableArray<TreeNode *> * treeArray = [NSMutableArray array]; TreeNode * root = [TreeNode nodeWithData:dataArray.firstObject.intValue]; [treeArray addObject:root]; for (int i = 1; i<dataArray.count; i++) { NSNumber * num = dataArray[i]; TreeNode * leftNode = [TreeNode nodeWithData:num.intValue]; TreeNode * father = treeArray.firstObject; [treeArray removeObject:father]; father.leftNode = leftNode; [treeArray addObject:leftNode]; i++; if (i>=dataArray.count) { break; } num = dataArray[i]; TreeNode * rightNode = [TreeNode nodeWithData:num.intValue]; father.rightNode = rightNode; [treeArray addObject:rightNode]; } return root; } + (TreeNode *)nodeWithData:(int)data { TreeNode * root = [[TreeNode alloc] init]; root.data = data; return root; } + (TreeNode *)nodeWithData:(int)data leftNode:(TreeNode *)leftNode rightNode:(TreeNode *)rightNode { TreeNode * root = [[TreeNode alloc] init]; root.data = data; root.leftNode = leftNode; root.rightNode = rightNode; return root; } - (NSString *)description { return [NSString stringWithFormat:@"%d %@ %@",self.data,self.leftNode,self.rightNode]; } @end - (void)viewDidLoad { [super viewDidLoad]; [self sumTree]; } /// 二叉树路径和 - (void)sumTree { // 测试用例 // TreeNode * root = [TreeNode nodeWithDataArray:nil]; // TreeNode * root = [TreeNode nodeWithDataArray:@[]]; // TreeNode * root = [TreeNode nodeWithDataArray:@[@(10)]]; // TreeNode * root = [TreeNode nodeWithDataArray:@[@(12),@(4),@(7)]]; TreeNode * root = [TreeNode nodeWithDataArray:@[@(10),@(5),@(12),@(4),@(7)]]; // TreeNode * root = [TreeNode nodeWithDataArray:@[@(1),@(2),@(3),@(4),@(5),@(6),@(7)]]; // TreeNode * root = [TreeNode nodeWithDataArray:@[@(1),@(2),@(3),@(4),@(5),@(6),@(7),@(8),@(9),@(10),@(11),@(12),@(13),]]; [self __sumAction:root]; } - (void)__sumAction:(TreeNode *)node { if (node == nil) { return; } // 用数组模拟一个栈栈结构 static NSMutableArray * array = nil; if (array == nil) { array = [NSMutableArray array]; } [array addObject:@(node.data)]; // 打印当前节点,和当前路径的和 NSLog(@"添加新node:%d sum:%@",node.data,[array valueForKeyPath:@"@sum.self"]); // 前序遍历,根->左->右 if (node.leftNode) { [self __sumAction:node.leftNode]; } if (node.rightNode) { [self __sumAction:node.rightNode]; } // 如果是叶子节点,打印 if (node.leftNode == nil && node.rightNode == nil) { NSLog(@"此路径完成,%@, 总和为: %@",[array componentsJoinedByString:@"->"],[array valueForKeyPath:@"@sum.self"]); } NSLog(@"移除此元素 %@",array.lastObject); [array removeLastObject]; }