?思路
二叉树顾名思义就是一个最多有两个子节点的数据结构,如下图所示。
其中像数字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)
- 2+4+7?=14-1 = 13
- 4+7?=13-2=11
- 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;
}
|