【含例题】树中边、度、点的关系

例题
一棵二叉树,度为2结点数为70,度为1结点数为176,则叶子结点数为( ).

A.71

B.69

C.175

D.177

在做这道题之前,要先理解一棵树中点数、度数和边数的关系。

对一棵n度树,设0度点(叶子节点)数量为 N 0 N_0 N0,1度点数量为 N 1 N_1 N1……n度点为 N n N_n Nn,列三个方程,即可求解节点数、度数、边数中的未知量。

1)节点数方程:

N 0 + N 1 + N 2 + . . . + N n = Σ i = 1 n N i = N V N_0 + N_1 + N_2 + ... + N_n = \Sigma_{i=1}^{n}Ni = N_V N0+N1+N2+...+Nn=Σi=1nNi=NV

意义:各度数的节点的数量加起来,等于总节点数( N V N_V NV, number of vertices)

下图中 N V = 7 , N 0 = 4 , N 1 = 0 , N 2 = 3 N_V=7,N_0=4,N_1=0,N_2=3 NV=7,N0=4,N1=0,N2=3

2)度数方程:

0 ∗ N 0 + 1 ∗ N 1 + 2 ∗ N 2 + . . . + n ∗ N n = N E 0 * N_0 + 1 * N_1 + 2 * N_2 + ... + n * N_n = N_E 0N0+1N1+2N2+...+nNn=NE

意义:各度数节点的数量乘上对应度数之和,等于总度数(Ne, number of edges)

下图中 N E = 6 N_E=6 NE=6

3)度数与边数方程:

N E = N V − 1 N_E = N_V - 1 NE=NV1
每个节点都有一条连接父节点的边,而根节点没有,所以要减掉1

root
V1
V2
V3
V4
V5
V6

秒杀例题

例题
一棵二叉树,度为2结点数为70,度为1结点数为176,则叶子结点数为( ).

A.71

B.69

C.175

D.177

还是一样的例题,不过我们已经有备而来。
首先,这是一棵二叉树,所以每个节点的度数只可能是0,1,2
接着,标出已知量 N 1 = 176 , N 2 = 70 N_1=176,N_2=70 N1=176,N2=70,要求的是 N 0 N_0 N0
然后,列三道方程:
1)节点数: N 0 + N 1 + N 2 = N V N_0+N_1+N_2=N_V N0+N1+N2=NV
< = > N 0 + 176 + 70 = N V <=> N_0 + 176 + 70 = N_V <=>N0+176+70=NV

2)度数: 1 ∗ N 1 + 2 ∗ N 2 = N E 1 * N_1 + 2 * N_2 = N_E 1N1+2N2=NE
< = > 176 + 140 = N E <=>176+140=N_E <=>176+140=NE
< = > N E = 316 <=>N_E=316 <=>NE=316

3)度边数: N E = N V − 1 N_E = N_V - 1 NE=NV1
< = > 316 = N V − 1 <=>316 = N_V - 1 <=>316=NV1
< = > N V = 317 <=>N_V=317 <=>NV=317

代回到①中:
N 0 + 176 + 70 = N V = 317 N_0 + 176 +70 =N_V = 317 N0+176+70=NV=317
< = > N 0 = 71 <=>N_0=71 <=>N0=71

最终得到本题答案为A

### 关于决策树的经典例题及其Java实现 #### 背景介绍 CatBoost 使用的是基于预测器构建的无意识决策树 (oblivious decision trees),这些树的特在于每一层都使用相同的分裂标准[^1]。这种特性使得它们更加平衡,减少了过拟合的风险,并显著提高了测试阶段的速。 尽管 CatBoost 的具体算法可能不适合初学者理解经典决策树的概念,但经典的决策树问题通常涉及分类或回归任务。以下是几个常见的决策树经典例子以及其对应的 Java 实现方法: --- #### 经典案例 1: Iris 数据集分类 Iris 数据集是一个非常著名的数据集,用于多类别的分类问题。它包了三种鸢尾花的数据(Setosa、Versicolor 和 Virginica),每种花有四个特征:萼片长、萼片宽、花瓣长和花瓣宽。 ##### 解决方案描述 可以使用 ID3 或 C4.5 决策树算法来解决此问题。ID3 算法通过计算信息增益选择最佳分割属性,而 C4.5 则进一步改进了这一过程。 ##### Java 实现代码 以下是一个简单的 Java 实现示例,展示如何加载数据并训练一个基本的决策树模型: ```java import java.util.ArrayList; import java.util.List; public class DecisionTreeExample { public static void main(String[] args) { List<String[]> data = new ArrayList<>(); // 添加样本数据 (简化版) data.add(new String[]{"long", "wide", "setosa"}); data.add(new String[]{"short", "narrow", "versicolor"}); data.add(new String[]{"medium", "wide", "virginica"}); System.out.println("Training Data:"); for (String[] sample : data) { System.out.println(sample[0] + ", " + sample[1] + " -> " + sample[2]); } // 构建决策树逻辑 (伪代码形式) Node root = buildDecisionTree(data); traverseAndPrint(root, ""); } private static Node buildDecisionTree(List<String[]> data) { // 基本逻辑:递归地划分数据直到满足停止条件 if (data.isEmpty()) { return null; // 如果没有更多数据,则返回空节 } else if (allSameClass(data)) { return new LeafNode(data.get(0)[2]); // 所有样本属于同一类别 } else { String bestAttribute = findBestSplittingAttribute(data); // 寻找最优分割属性 List<String[]> subsets = splitDataByAttribute(data, bestAttribute); InternalNode node = new InternalNode(bestAttribute); int index = 0; for (List<String[]> subset : subsets) { node.addChild(buildDecisionTree(subset), getAttributeValue(index++)); } return node; } } private static boolean allSameClass(List<String[]> data) { String firstLabel = data.get(0)[2]; for (String[] sample : data) { if (!sample[2].equals(firstLabel)) { return false; } } return true; } private static String findBestSplittingAttribute(List<String[]> data) { // 计算信息增益或其他指标以找到最佳属性 return "length"; // 示例中假设为 length 属性 } private static List<List<String[]>> splitDataByAttribute(List<String[]> data, String attribute) { // 将数据按指定属性划分为子集 List<List<String[]>> result = new ArrayList<>(); // 这里省略实际实现细节... return result; } private static String getAttributeValue(int index) { switch (index) { case 0: return "long"; case 1: return "short"; default: return "medium"; } } private static void traverseAndPrint(Node node, String indent) { if (node instanceof LeafNode) { System.out.println(indent + ((LeafNode) node).getClassLabel()); } else if (node instanceof InternalNode) { System.out.println(indent + ((InternalNode) node).getAttributeName() + ":"); for (Node child : ((InternalNode) node).getChildren().keySet()) { traverseAndPrint(child, indent + " "); } } } } abstract class Node {} class InternalNode extends Node { private final String attributeName; private final List<Node> children; public InternalNode(String attributeName) { this.attributeName = attributeName; this.children = new ArrayList<>(); } public String getAttributeName() { return attributeName; } public List<Node> getChildren() { return children; } public void addChild(Node child, String value) { // 存储孩子节与对应值的关系 } } class LeafNode extends Node { private final String classLabel; public LeafNode(String classLabel) { this.classLabel = classLabel; } public String getClassLabel() { return classLabel; } } ``` 上述代码展示了如何手动构建一棵决策树,并打印出它的结构。 --- #### 经典案例 2: 数字识别 (MNIST 数据集) 虽然 MNIST 更适合复杂的机器学习模型(如神经网络),但它也可以被简化成一个小规模的问题供决策树练习。 ##### 解决方案描述 对于较小版本的 MNIST 数据集,可以通过提取像素强作为特征来进行分类。由于原始图像大小较大,建议先降维再应用决策树。 ##### Java 实现思路 类似于 Iris 数据集的例子,只需替换输入数据即可完成该任务。 --- #### 经典案例 3: 温控制系统的优化 这是一个典型的回归问题,目标是根据环境温调整空调设置。 ##### 解决方案描述 可以设计一组规则表示不同条件下应采取的操作,例如当室内温高于某个阈值时开启制冷模式。 ##### Java 实现片段 ```java // 定义一些简单规则 if (temperature > THRESHOLD_HIGH) { action = COOLING_MODE; } else if (temperature < THRESHOLD_LOW) { action = HEATING_MODE; } else { action = MAINTAIN_MODE; } ``` --- ### 总结 以上三个案例分别代表了不同的应用场景——分类、手写数字识别和回归分析。通过这些实例可以帮助开发者更好地掌握决策树的工作原理及其在现实世界中的用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值