我们举例来做分析,如下图所示,我们准备了一颗二叉树和一个整数22,通过观察后,我们很容易就能看出它有两条路径的节点值加起来和为22。
成都创新互联专注于企业营销型网站、网站重做改版、天涯网站定制设计、自适应品牌网站建设、H5页面制作、商城网站建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为天涯等各大城市提供网站开发制作服务。
上述两个路径都是从根节点出发到叶子节点的,也就是说路径总是以根节点为起始点,因此我们首先需要遍历根节点。在树的三种遍历方式中,只有前序遍历是首先访问根节点的。
按照前序遍历的顺序去访问这颗二叉树,在访问节点10之后,就会访问节点5。图中二叉树并没有指向父节点的指针,当访问节点5的时候,我们是不知道前面经过了哪些节点的,此时我们就需要准备一个栈,用来存储访问过的节点。
当到达节点5的时候,路径中包含两个节点:10、5。接下来遍历到节点4,我们把这个节点入栈,这时候已经到达叶节点,但栈中的所有节点之和是19。这个和不等于输入的值22,因此它不符合要求的路径。
最后,我们要遍历的节点是12。在遍历这个节点之前,需要先经过节点5回到节点10。同样的,每次当从子节点回到父节点的时候,我们都需要在路径上删除子节点。最后在节点10到达节点12的时候,路径上的两个节点的值之和也是22,因此这也是一条符合要求的路径。
递归上述过程,直至二叉树的所有节点访问完毕。
形成了清晰的思路之后,接下来我们就可以轻松的写出代码了,如下所示:
findPath(root: Node, expectedSum: number): Array {
if (root == null) return [];
// 用一个栈来存储访问过的路径
const pathStack = new Stack();
// 存储符合条件的路径
const pathList: Array= [];
// 当前已访问路径总和
const currentSum = 0;
// 从root节点开始搜索节点
this.searchNode(root, expectedSum, pathStack, currentSum, pathList);
return pathList;
}
private searchNode(
root: Node,
expectedSum: number,
pathStack: Stack,
currentSum: number,
pathList: Array
) {
// 累加当前已访问节点的和,将当前节点入栈
currentSum += root.key;
pathStack.push(root.key);
// 如果是叶节点,并且路径上节点值的和等于输入的值,则存储当前路径栈中的节点
const isLeaf = root.left == null && root.right == null;
if (currentSum == expectedSum && isLeaf) {
pathList.push(pathStack.toString());
}
// 非叶子节点,则遍历它的子节点
if (root.left != null) {
this.searchNode(root.left, expectedSum, pathStack, currentSum, pathList);
}
if (root.right != null) {
this.searchNode(root.right, expectedSum, pathStack, currentSum, pathList);
}
// 当前节点不符合条件,将其出栈
pathStack.pop();
}
接下来我们用文章开头的例子来测试下上述代码能否正确执行。
const tree: Node= {
key: 10,
left: {
key: 5,
left: {
key: 4
},
right: {
key: 7
}
},
right: {
key: 12
}
};
const targetVal = 22;
const resultPath = treeOperateTest.findPath(tree, targetVal);
console.log(resultPath);
如下所示,成功得计算出了两条路径。
我们将节点12改成20,再来测试下,结果如下所示,只有一条路径符合预期。
本文用到的代码完整版请移步:
网站栏目:二叉树中和为某一值的路径
转载来源:http://www.gawzjz.com/qtweb2/news43/8343.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联