C语言算法题之二叉树的路径和

本文介绍如何在给定的二叉树中寻找路径和等于指定值的方法,通过递归遍历节点并调整路径和,展示了如何使用C语言实现判断是否存在满足条件的路径。

 思路

二叉树顾名思义就是一个最多有两个子节点的数据结构,如下图所示。

其中像数字7和8,5和6这四个节点都叫做叶子节点,其他的节点都是叫做根节点。 路径有:

  • 1-2-4-7(路径和为1+2+4+7=14)
  • 1-2-4-8(路径和为1+2+4+8=15)
  • 1-2-5(路径和为1+2+5=8)
  • 1-3-6 (路径和为1+3+6=10)

给定一个二叉树和指定值,那么如何便利路径和并比较是否等于指定值呢?可以将路径和看作是一个算式,算式左边等于各路径上的节点之和,算式右边等于指定值。然后通过移相的方式来比较算式两边的值是否相等,比如1-2-4-7这个路径可以分为以下几步:(以下等式用?=表示是否等于,假设指定值就是14)

  1. 2+4+7?=14-1 = 13
  2. 4+7?=13-2=11
  3. 7?=11-4

同理可得其他路径之和是否等于该指定值,编程实现如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
 
/// 声明代表一个二叉树节点的数据结构
typedef struct Node {
    int value;
    struct Node *left;
    struct Node *right;
} Node, *Tree;

/// 创建一个二叉树(前序法)
/// @param T 指向二叉树的指针
/// @param flag 0:代表根节点 -1:代表左节点 1:代表右节点
void CreateBiTree(Tree *T, int flag)
{
    int val;
    flag != 0 ? (flag == -1 ?
                 printf("请输入左节点的值:") :
                 printf("请输入右节点的值:")) :
                printf("请输入根节点的值:");
    scanf("%d",&val);
    //以0作为空节点
    if(val == 0) {
        *T = NULL;
    } else {
        *T = malloc(sizeof(Node));
        if(*T == NULL) exit(-1);
        (*T)->value=val;
        CreateBiTree(&(*T)->left, -1);
        CreateBiTree(&(*T)->right, 1);
    }
}

/// 判断指定二叉树是否至少有一条路径和等于指定值
/// @param T 二叉树
/// @param orderSum 指定值
bool hasPathSameOrderSum(Tree T, int orderSum) {
    if (T == NULL) {
        return false;
    }
    if (T->left == NULL && T->right == NULL && T->value == orderSum) {
        free(T);
        return true;
    }
    
    Tree left = T->left;
    Tree right = T->right;
    int value = T->value;
    free(T);
    return (hasPathSameOrderSum(left, orderSum-value) || hasPathSameOrderSum(right, orderSum-value));
}
 
int main(int argc, const char * argv[]) {
    Tree tree = NULL;
    printf("创建一个二叉树\n");
    CreateBiTree(&tree, 0);
    int sum;
    printf("请输入指定路径和:");
    scanf("%d", &sum);
    if (hasPathSameOrderSum(tree, sum)) {
        printf("该二叉树至少有一条路径和等于%d", sum);
    } else {
        printf("该二叉树任意一条路径和都不等于%d", sum);
    }
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星仔20180409

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值