二叉树中和为某一值的路径

本文介绍了一种使用前序遍历方法寻找二叉树中所有节点值之和等于指定整数的路径的方法。通过创建二叉搜索树并利用栈结构记录路径,实现了路径的有效查找与输出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:
输入一棵二叉树和一个整数,打印出二叉树和中节点值和为输入整数的所有路径,从树的根节点开始往下一直到叶子节点所经过的节点形成的一条路径。
这里写图片描述
输入的二叉树如图,输入的整数为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;
}

调试结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值