二叉树中和为某一值的路

2024-06-22 14:18
文章标签 二叉树 一值

本文主要是介绍二叉树中和为某一值的路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题意描述:输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。如:
        10
        /    \
      5    12
    /   \

  4    7

解题思路:借助栈,进行深度优先遍历,如果当前结点为叶子结点并且从根结点到当前结点的值的和等于给定值,则找到一条路径并打印,否则继续向叶结点遍历或者返回上一级,返回上一级时需要在当前计算的和的基础上减去当前结点的值

(C++版本)

struct BinaryTreeNode {int m_nValue;BinaryTreeNode* m_pLeft;BinaryTreeNode* m_pRight;
};//创建二叉树结点
BinaryTreeNode* CreateBinaryTreeNode(int value) {BinaryTreeNode* pNode = new BinaryTreeNode();pNode->m_nValue = value;pNode->m_pLeft = NULL;pNode->m_pRight = NULL;return pNode;
}//连接二叉树结点
void ConnectionTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight) {if (pParent != NULL) {pParent->m_pLeft = pLeft;pParent->m_pRight = pRight;}
}void findPath(BinaryTreeNode* pRoot, int expectedSum, vector<int>& path, int currentSum) {currentSum += pRoot->m_nValue;path.push_back(pRoot->m_nValue);//如果是叶结点,并且路径上结点的和等于输入的值打印出这条路径bool isLeaf = (pRoot->m_pLeft == NULL) && (pRoot->m_pRight == NULL);if (isLeaf && (currentSum == expectedSum)) {cout << "A path is found: ";//vector<int>::iterator it = path.begin();//for (; it != path.end(); ++it)//	cout << *it << " ";for (vector<int>::size_type i = 0; i < path.size(); i++)cout << path[i] << " ";cout << endl;}//如果不是叶结点if (pRoot->m_pLeft != NULL)findPath(pRoot->m_pLeft, expectedSum, path, currentSum);if (pRoot->m_pRight != NULL)findPath(pRoot->m_pRight, expectedSum, path, currentSum);//在返回父结点之前,在路径上删除当前结点path.pop_back();
}void findPath(BinaryTreeNode* pRoot, int expectedSum) {if (pRoot == NULL)return;vector<int> path;int currentSum = 0;findPath(pRoot, expectedSum, path, currentSum);
}//先序遍历
void InOrder(BinaryTreeNode* pTreeRoot) {	if (pTreeRoot->m_pLeft != NULL)InOrder(pTreeRoot->m_pLeft);cout << pTreeRoot->m_nValue << " ";if (pTreeRoot->m_pRight != NULL)InOrder(pTreeRoot->m_pRight);
}int main()
{BinaryTreeNode* node1 = CreateBinaryTreeNode(10);BinaryTreeNode* node2 = CreateBinaryTreeNode(5);BinaryTreeNode* node3 = CreateBinaryTreeNode(12);BinaryTreeNode* node4 = CreateBinaryTreeNode(4);BinaryTreeNode* node5 = CreateBinaryTreeNode(7);ConnectionTreeNodes(node1, node2, node3);ConnectionTreeNodes(node2, node4, node5);InOrder(node1);cout << endl;findPath(node1, 22);return 0;
}

(Java版本)

class BinaryTreeNode{int value;BinaryTreeNode leftNode;BinaryTreeNode rightNode;
}public class FindPath {		//解题思路:借助栈,进行深度优先遍历,如果当前结点为叶子结点并且从根结点到当前结点的值的和等于给定值,则找到一条路径并打印//否则继续向叶结点遍历或者返回上一级,返回上一级时需要在当前计算的和的基础上减去当前结点的值public static void findPath(BinaryTreeNode root, int expectedSum){if(root == null)return;Stack<Integer> stack = new Stack<Integer>();int currentSum = 0;findPath(root, currentSum, stack, expectedSum);}public static void findPath(BinaryTreeNode root,int currentSum, Stack<Integer> path, int expectedSum){currentSum += root.value;path.add(root.value);//如果是叶结点,并且路径上结点的和等于输入的值则打印boolean isLeaf = (root.leftNode==null)&&(root.rightNode==null);if(isLeaf && (currentSum == expectedSum)){System.out.print("A path find: ");for(int n : path)System.out.print(n + " ");System.out.println();}//如果不是叶结点if(root.leftNode != null)findPath(root.leftNode, currentSum, path, expectedSum);if(root.rightNode != null)findPath(root.rightNode, currentSum, path, expectedSum);//在返回父结点之前把路径上的当前结点删除path.pop();}public static void main(String[] args) {BinaryTreeNode root = new BinaryTreeNode();BinaryTreeNode node1 = new BinaryTreeNode();BinaryTreeNode node2 = new BinaryTreeNode();BinaryTreeNode node3 = new BinaryTreeNode();BinaryTreeNode node4 = new BinaryTreeNode();root.leftNode = node1;root.rightNode = node2;node1.leftNode = node3;node1.rightNode = node4;root.value = 10;node1.value = 5;node2.value = 12;node3.value = 4;node4.value = 7;findPath(root, 22);}}

(Golang版本)

package mainimport (list2 "container/list""fmt"
)// 二叉树结构
type BTree struct {Val   intLeft  *BTreeRight *BTree
}// 构建一棵二叉树
//      8
//    /   \
//   6     10
//  / \    / \
// 5   7  9   11
func newBTree() *BTree {node2_1 := &BTree{Val: 5}node2_2 := &BTree{Val: 7}node2_3 := &BTree{Val: 9}node2_4 := &BTree{Val: 11}node1_1 := &BTree{Val: 6, Left: node2_1, Right: node2_2}node1_2 := &BTree{Val: 10, Left: node2_3, Right: node2_4}root := &BTree{Val: 8, Left: node1_1, Right: node1_2}return root
}/** 求二叉树和为某值的所有路径*/
func findPath(root *BTree, expSum int) {if root == nil {return}path := newStack()curSum := 0solution(root, curSum, expSum, path)
}
func solution(root *BTree, curSum, expSum int, path *myStack) {curSum += root.Valpath.push(root)if root.Left == nil && root.Right == nil && curSum == expSum {for ele := path.List.Front(); ele != nil ; ele = ele.Next()  {node := ele.Value.(*BTree)fmt.Printf("%d\t", node.Val)}fmt.Println()}if root.Left != nil {solution(root.Left, curSum, expSum, path)}if root.Right != nil {solution(root.Right, curSum, expSum, path)}path.pop()
}func main() {root := newBTree()findPath(root, 21)
}/
// 自定义栈
type myStack struct {List *list2.List
}func newStack() *myStack {stack := myStack{List: list2.New()}return &stack
}func (stack *myStack) push(ele interface{}) {stack.List.PushBack(ele)
}func (stack *myStack) pop() interface{} {if ele := stack.List.Back(); ele != nil {stack.List.Remove(ele)return ele.Value}return nil
}func (stack *myStack) len() int {return stack.List.Len()
}// 自定义队列
type myQueue struct {List *list2.List
}func newQueue() *myQueue {queue := myQueue{List: list2.New()}return &queue
}func (queue *myQueue) push(ele interface{}) {queue.List.PushBack(ele)
}func (queue *myQueue) pop() interface{} {if ele := queue.List.Front(); ele != nil {queue.List.Remove(ele)return ele.Value}return nil
}func (queue *myQueue) len() int {return queue.List.Len()
}

 

 

 

 

 

这篇关于二叉树中和为某一值的路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1084524

相关文章

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

在二叉树中找到两个节点的最近公共祖先(基于Java)

如题  题解 public int lowestCommonAncestor(TreeNode root, int o1, int o2) {//记录遍历到的每个节点的父节点。Map<Integer, Integer> parent = new HashMap<>();Queue<TreeNode> queue = new LinkedList<>();parent.put(roo

数据结构--二叉树(C语言实现,超详细!!!)

文章目录 二叉树的概念代码实现二叉树的定义创建一棵树并初始化组装二叉树前序遍历中序遍历后序遍历计算树的结点个数求二叉树第K层的结点个数求二叉树高度查找X所在的结点查找指定节点在不在完整代码 二叉树的概念 二叉树(Binary Tree)是数据结构中一种非常重要的树形结构,它的特点是每个节点最多有两个子节点,通常称为左子节点和右子节点。这种结构使得二叉树在数据存储和查找等方面具

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

222.完全二叉树的节点个数

(写给未来遗忘的自己) 题目: 代码: class Solution {public:int countNodes(TreeNode* root) {queue<TreeNode*>node_que;if(root==nullptr) return 0;node_que.push(root);int result;while(!node_que.empty()){int layer_s

代码随想录 -- 二叉树 -- 平衡二叉树

110. 平衡二叉树 - 力扣(LeetCode) 思路:仍然是递归调用 1. 定义一个递归函数 count 用来计算二叉树的层数 2. isBalanced 函数:如果传入根节点为空返回真;如果根节点 | 左子树的层数 - 右子树的层数 | 大于1,返回假;最后返回根节点左子树、右子树是否是平衡二叉树。 class Solution(object):def count(self,root

【数据结构】你真的学会了二叉树了吗,来做一做二叉树的算法题及选择题

文章目录 1. 二叉树算法题1.1 单值二叉树1.2 相同的树1.3 另一棵树的子树1.4 二叉树的遍历1.5 二叉树的构建及遍历 2. 二叉树选择题3. 结语 1. 二叉树算法题 1.1 单值二叉树 https://leetcode.cn/problems/univalued-binary-tree/description/ 1.2 相同的树 https://leet

二叉树的层次遍历(10道)

(写给未来遗忘的自己) 102.二叉数的层序遍历(从上到下) 题目: 代码: class Solution { public: vector<vector<int>> levelOrder(TreeNode* root) { vector<vector<int>> result; queue<TreeNode*> node; if (root == nullptr) {

求二叉树的深度——(力扣c语言)

题目如下: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1: 输入:root = [3,9,20,null,null,15,7]输出:3 示例 2: 输入:root = [1,null,2]输出:2 题目解析: 上题就是要利用递归对目标进行访问找到叶子节点之后记录并返回到根节点之后对左右两个