您的位置:首页 > 其它

算法题23 在二元树中找出和为某一值的所有路径

2011-05-18 00:12 417 查看
题目:输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如 输入整数22和如下二元树
10
/ /
5 12
/ /
4 7
则打印出两条路径:10, 12和10, 5, 7。



此题考察二叉树的先序遍历。



通过建立辅助栈。先序遍历树,

1、如果节点为null,返回

2、计算栈内所有节点数值与当前节点数值的和,如果结果大于期望值,此路不通,返回;如果结果小于期望值且当前节点不为叶子,把当前节点进栈,继续遍历,否则返回;如果当前节点为叶子,且和正好是期望值,当前栈内节点和当前叶子节点组成的路径即是所求路径。

3、遍历左子树

4、遍历右子树



代码:

template<typename T>
struct TreeNode
{
	T data;
	TreeNode* pLChild;
	TreeNode* pRChild;
};
#include <deque>
// 输出和为sum的所有路径
void PrintPathBy(TreeNode<int>* pRoot, int sum)
{
	static std::deque<int> stack;
	static int sSum = 0;
	if(pRoot == NULL)
	{
		return;
	}
	// 如果当前节点是叶子,则是该路径的终点
	if(pRoot->pLChild == NULL && pRoot->pRChild == NULL)
	{
		if(sSum + pRoot->data == sum)
		{
			// 此为一个目标路径,打印出来,并且出栈一个节点
			for(std::deque<int>::const_iterator iter = stack.begin(); iter != stack.end(); ++iter)
			{
				printf("%d ", *iter);
			}
			printf("%d/n", pRoot->data);
			sSum -= stack.back();
			stack.pop_back();
		}
		return;
	}
	else if(sSum + pRoot->data < sum)
	{
		// 如果新节点加入,小于sum,进栈
		stack.push_back(pRoot->data);
		sSum += pRoot->data;
	}
	else
	{
		// 此路不通
		return;
	}
	// 先序遍历左子树
	PrintPathBy(pRoot->pLChild, sum);
	// 遍历右子树
	PrintPathBy(pRoot->pRChild, sum);
}




测试代码:

#include <iostream>
// 先序递归创建二叉树,非数字字符表示叶子节点
// 输入数据:'#'作为叶节点
void CreateTree(TreeNode<int>*& pRoot)
{
	char buffer[10];
	memset(buffer, 0, 10);
	std::cin.getline(buffer, 9);
	int a = atoi(buffer);
	if(a == 0) pRoot = NULL;
	else
	{
		pRoot = new TreeNode<int>();
		pRoot->data = a;
		pRoot->pLChild = pRoot->pRChild = NULL;
		CreateTree(pRoot->pLChild);
		CreateTree(pRoot->pRChild);
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	TreeNode<int>* pTree = NULL;
	CreateTree(pTree);
	
	printf("输出结果:/n");
	PrintPathBy(pTree, 22);
	system("pause");
	return 0; 
}




输入及输出结果:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐