使用递归在二叉树中查找鞍点

时间:2015-02-10 18:46:11

标签: algorithm recursion binary-tree

我想找到T,二叉树的鞍点,如果有的话。 鞍点在其所有祖先中具有最小值,但在其所有后代中具有最大值。如果叶子的价值低于它的所有祖先,那么叶子就可以成为这样的鞍点。

示例树:

              F:15
         E:16        H:17
    B:14         G:16    I:8
 A:8    C:7
           D:5

B是一个这样的鞍点,因为14小于16和15,但也大于8,7和5. A,C,D和I是其他鞍点。

我试着想办法递归检查每个子树,并证明父节点是其所有后代中的最大值。但是,由于C(16)是其所有后代中的最大值但大于F(15),因此它不是鞍点,因此该方法不正确。

解决问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

编写一个函数find_saddle,它接受​​一个节点,以及父节点的最小值(默认为根节点的INT_MAX)。它将返回最大的孩子的价值。当调用该函数时,它会计算出一个孩子可以拥有的最大值,并且可能是一个马鞍,它本身的最小值和最小父母。然后以最小值向左和向右递归,并收到每个子树中的最大值。如果节点自己的值大于bolth子树的最大值但小于父亲的最小值,那么它就是一个马鞍并且......无论你想要什么。最后,它返回它自己的最大值和两个子树最大值。

int find_saddle(node* n, int parent_min=INT_MAX) {
   int child_min = min(n->value, parent_min);

   int left_max = INT_MIN;
   if (n->left)
       left_max = find_saddle(n->left, child_min);

   int right_max= INT_MIN;
   if (n->right) 
       right_max = find_saddle(n->right, child_min);

   int child_max = max(left_max, right_max); 

   if (n->value > child_max && n->value < parent_min)
       do_thing(n);

   return max(child_max, n->value);
}

此代码假设树叶可以是鞍点,但调整它以排除这些节点并不是很难。