大家好,我是「阑梦清川」
今天我们看到的这个题目是:给定一棵二叉搜索树以及对应的一个整数。
需要我们从这棵树里面找到和这个整数差值绝对值最小的节点,并输出该绝对值与节点对应的关键字。
我们需要:

首先我们介绍一下基本的概念,什么是二叉树?
想要解决这个问题,我们需要理解两个核心概念:二叉树和它的升级版二叉搜索树(BST)。
什么是二叉树?
二叉树是一种数据结构,每个节点最多有两个孩子,分为左孩子和右孩子。它就像家谱一样,一个父亲最多有两个子女。虽然现实中显然不是这个样子,但针对二叉树,一个节点最多只能有两个子节点,即左节点和右节点。
什么是二叉搜索树?
二叉搜索树是二叉树的一种特殊形式,它有一个非常重要的排序规则:
(a) 左子树上所有节点的值要小于它的根节点的值
(b) 右子树上所有节点的值要大于它的根节点的值
如果我们对二叉搜索树进行中序遍历,它实际上是按照一个递增的有序序列进行排列的,这是它的一个特点。
题目问的是什么?
题目给定了一棵二叉搜索树和一个整数 k,让我们去这棵树里面找到哪一个节点的值和 k 最接近,也就是差的绝对值最小。如果有多个节点满足条件,都需要找出来。最后我们需要输出这个最小的差值和对应的节点数值。
我们可以这样思考这个问题:既然二叉搜索树(BST)是有序的,如果我们现在站在一个节点上,发现它的数值是 10,而我们需要查找的 k 是 15。根据 BST 的规则,你觉得比 10 更接近 15 的数,更有可能出现在它的左子树还是右子树呢?
利用 BST 的结构特点:左子树的所有数值都比根节点小,右子树的所有数值都比根节点大。
- 我们现在来到值为 10 的节点,当前的差值是 5,将其作为最小差值的一个候选值。
- 如果我们向左走,左子树里的数比 10 还要小,那么它与 15 的距离肯定会大于 5。
- 如果我们向右走,这些数比 10 大,它们的差值可能会比 5 更小,也就是离 15 更近。
所以,如果当前节点的值小于 k,为了找到更接近 k 的值,我们应该去查找右子树。这种特性允许我们像在有序数组中做二分查找一样,每一次比较都能排除掉整整一半的分支,大大提高了搜索效率。
虽然右子树更有潜力,但我们不能直接跳过去,而是要带着当前的最小差值去比较。我们需要处理一种特殊情况,即差值相同的情况。比如 k 等于 15,而节点 13 和节点 17 与它的距离一样近。如果题目要求找出所有最接近的节点,我们就需要在更新最小差值的同时,把对应的节点数值记录下来。
整理一下我们的算法逻辑,可以使用递归的方法来遍历这棵树:
- 计算当前节点值与目标值 k 的差的绝对值,即 CurrentDifference。
- 更新结果:
(a) 如果 CurrentDifference 小于 MinDifference:清空列表,放入当前值,并更新 MinDifference。
(b) 如果 CurrentDifference 等于 MinDifference:说明找到了多个最小差值节点,将当前值放入结果列表。 - 利用 BST 的特性决定去向:决定是去左子树还是右子树。
现在我们需要结合 BST 的性质想一想:如果某个节点的数值已经正好等于 k,此时差值为 0,那么还有必要搜索它的左子树和右子树吗?
实际上,虽然差值不会比 0 更小,但在标准的二叉搜索树中,通常规定节点值是唯一的。如果题目假设树中没有重复值,那么一旦找到了差值为 0 的节点,我们确实可以立即停止搜索,因为它是唯一最接近的节点。
算法实现:

我是「阑梦清川」,希望得到您的关注