剑指offer 4.3 举例形象化问题5-二叉树中和为某一值的路径

题目:输入一个整数和一棵二元树。从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。打印出和与输入整数相等的所有路径。

例如输入整数22和如下二元树

                                            10
                                           /   \
                                          5     12
                                        /   \   
                                      4     7 

则打印出两条路径:10, 1210, 5, 7

二元树结点的数据结构定义为:

struct BinaryTreeNode // a node in the binary tree
{
      int              m_nValue; // value of node
      BinaryTreeNode  *m_pLeft;  // left child of node
      BinaryTreeNode  *m_pRight; // right child of node
};

分析:这是百度的一道笔试题,考查对树这种基本数据结构以及递归函数的理解。

前序遍历访问这个二叉树,访问到某一节点时,把该节点添加到路径上,并保存该节点的值。


如果该节点为叶子节点,并且路径中节点值之和刚好等于 输入的整数,则当前路径符合要求,打印之;

如果当前节点不是叶子节点,则继续访问他的子节点。

当前节点访问结束后,递归函数需要自动回到他的父节点。

因此,在函数退出之前要在路径上删除当前节点,并减去当前节点的值,以确保返回父节点时路径刚好是从根节点到父节点的路径。

保存路径使用栈,因为路径要与递归调用一致。(递归调用本身是一个压栈和出栈的过程)

<pre name="code" class="cpp">struct binaryTree {
	int value;
	binaryTree *left;
	binaryTree *right;

};
void findPath(binaryTree *root, int expectedSum, vector<int> &path, int currentSum) {
	currentSum += root->value;
	path.push_back(root->value);

	// 如果expectedSum等于路径中记录的值,且当前节点是叶子节点,则找到该路径
	bool isLeaf = root->left == NULL && root->right == NULL;
	if(currentSum == expectedSum && isLeaf) {
		cout << "the path has been found: "<< endl;
		vector<int>::iterator iter = path.begin();

		for(; iter != path.end(); iter ++) {
			cout << *iter << "\t";
		}
		cout << endl;
	}

	// 如果不是叶子节点,则遍历其左右孩子
	if(root->left  != NULL)
		findPath(root->left, expectedSum, path, currentSum);
	if(root->right  != NULL)
		findPath(root->right, expectedSum, path, currentSum);

	// 返回到父节点时,在路径上删除当前节点
	currentSum -= root->value;<span style="color:#ff0000;">// 这句话让我很纳闷,我在vc上单步调试的时候, 不写这句话,也会currentSum也会减,不解</span>
		path.pop_back();
}
void find(binaryTree *root, int expectedSum) {
	if(root == NULL)
		return;
	vector<int> path;
	int currentSum = 0;
	findPath(root, expectedSum, path, currentSum);
}


 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值