题目:
输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径,打印出和与输入的整数相等的所以路径。
例如:输入整数为22,以及如下二叉树:
10
/ \
5 12
/ \
4 7
则打印出两条路径:10,12 和 10,5,7
ANSWER:
这个题目就是要遍历一遍二叉树就可以了,不过需要在二叉树的遍历基础上增加一些操作:回溯;
在从根遍历到树叶时,如果还有结点没有被遍历过,那么我们需要回溯回来,继续遍历没有被遍历过的结点,回溯最简单的实现就是递归;
在遍历的过程中,需要注意完成既定的功能:
数组path:存放当前遍历的路径上的结点的data值
变量sum:开始时赋值为程序输入的整数,减去path中的所有data后还剩余的数;如果为0,那么就输出当前path中记录的结点
代码:
#include<iostream>
#include<windows.h>
using namespace std;
struct node
{
int data;
node *left;
node *right;
node(int d)
{
data = d;
left = NULL;
right =NULL;
}
};
void helper(node *root,int sum,int *path,int top);
void printPath(node *root,int sum)
{
int path[MAX_PATH];
helper(root,sum,path,0);
}
void helper(node *root,int sum,int *path,int top)
{
if(root == NULL)
return;
sum -= root->data;
path[top++] = root->data;
if(sum == 0)
{
for(int i=0;i!=top;++i)
cout<<path[i]<<" ";
cout<<endl;
}
helper(root->left,sum,path,top);
helper(root->right,sum,path,top);
sum += root->data;
--top;
}
int main()
{
node *root = new node(10);
root->left = new node(5);
root->right = new node(12);
root->left->left = new node(4);
root->left->right = new node(7);;
printPath(root,22);
return 0;
}
参考上面的代码,我们可以将这个题目和No1那个二叉搜索树变双向链表的题目对比一下,学习递归,第一题中对所有参数的操作是放在递归调用后面的,那么这种递归一定是要到树的叶子结点才开始对参数进行操作,修改,如第一题中,先对叶子结点进行指针重定向,然后再对父结点的指针进行重定向;
而这一题中,我们将对本结点的相关操作放在递归调用之前,这是和第一题中不一样的地方呀,最后为了回溯回来,将用于模拟栈的数组的大小减1,标示着退出该结点。