题目:
输入一棵二叉树和一个整数,打印出二叉树和中节点值和为输入整数的所有路径,从树的根节点开始往下一直到叶子节点所经过的节点形成的一条路径。
输入的二叉树如图,输入的整数为22。
则打印两条路径:
10、12
10、5、7
思路:用前序遍历的方式访问某一个节点时,把该节点添加到路径上,并累加该节点的值,如果该节点为叶子节点并且累加的值正好为目标值,则输出该路径,如果不是叶子节点或者或者累加值不是目标值,则继续访问访问他的子节点,当前节点访问结束后,递归函数将自动回到他的父节点,所以,在函数返回到上一层时,要删除路径中的当前节点的值,我们不难看出保存路径的数据结构实际上是一个栈,因为路径要与递归调用状态一致,而递归的本质就是一个入栈和出栈的过程。
实现:
/*
创建二叉搜索树
*/
//定义二叉树的节点
typedef struct node{
int data;
struct node *left;
struct node *right;
}BTNode;
//创建二叉搜索树
BTNode* creatBinSortTree(int data[], int len){
BTNode *root = NULL, *p = NULL, *pa = NULL, *c = NULL;
for (int i = 0; i < len; i++){
//为二叉树分配节点
p = (BTNode*)malloc(sizeof(BTNode));
//初始化节点
p->data = data[i];
p->left = p->right = NULL;
if (!root){
root = p;
}
else{
c = root;
while (c){
pa = c;
if (c->data < p->data){
c = c->right;
}
else{
c = c->left;
}
}
if (pa->data < p->data){
pa->right = p;
}
else{
pa->left = p;
}
}
}
return root;
}
//中序遍历二叉树
void inOrder(BTNode *root){
if (root){
inOrder(root->left);
printf("%d ",root->data);
inOrder(root->right);
}
}
/*
用双向链表实现栈
*/
//定义栈节点
typedef struct s{
BTNode *pb;
struct s *pa;
struct s *next;
}Stack;
//压栈函数
void pushStack(Stack **top, BTNode *pb){
//为入栈元素分配单元
Stack *pnew = (Stack*)malloc(sizeof(Stack));
//初始化入栈节点
pnew->pa = pnew->next = NULL;
pnew->pb = pb;
if (!(*top)){
*top = pnew;
}
else{
(*top)->next = pnew;
pnew->pa = (*top);
*top = (*top)->next;
}
}
//弹栈函数
BTNode* popStack(Stack **top){
if (!(*top)){
return NULL;
}
//获取出栈元素
BTNode *pb = (*top)->pb;
Stack *ps = *top;
*top = (*top)->pa;
if (*top){
(*top)->next = NULL;
}
free(ps);
return pb;
}
//打印栈
void printStack(Stack **top){
if (*top){
printStack(&((*top)->pa));
printf("%d ",(*top)->pb->data);
}
}
void findPathCore(BTNode *root, int sum, Stack **path, int tag){
//存入路径
sum += root->data;
//将该节点压栈
pushStack(path, root);
//如果是叶子节点,并且该路径上的节点值等于目标值
//打印该路径
if (root->left == NULL&&root->right == NULL&&sum == tag){
printStack(path);
printf("\n\n");
}
//如果不是叶子节点则继续遍历他的子节点
if (root->left){
findPathCore(root->left, sum, path, tag);
}
if (root->right){
findPathCore(root->right, sum, path, tag);
}
//在返回父节点之前,删除在路径上的当前节点
popStack(path);
}
void findPath(BTNode *root, int tag){
if (root == NULL){
return;
}
Stack *path = NULL;
int sum = 0;
findPathCore(root, sum, &path, tag);
}
int main(void){
int data[5] = { 10,5,12,4,7 };
BTNode *root = creatBinSortTree(data, 5);
inOrder(root);
printf("\n符合条件的路径\n");
findPath(root, 22);
system("pause");
return 0;
}
调试结果: