【问题标题】:Find Predecessor in a BST在 BST 中查找前任
【发布时间】:2019-05-10 17:22:13
【问题描述】:

我想在不使用父指针的情况下递归且高效地搜索二叉搜索树中的前任。 我将树的根和某些数据(可以包含或不包含在 BST 中)作为函数的参数。

我遇到了麻烦,因为如果 BST 不包含数据,该函数应该在输出中给出小于它的最大值。

Node *recPredecessor(Node *root, int data, Node *pred){
    if(root->key > data){
        return recPredecessor(root->left, data, pred);
    }
    if(root->key < data){
        return recPredecessor(root->right, data, root);
    }
    if((root == NULL) || (root->key == data)){
        if(root == NULL){
            return pred;
        }
        if(root->key == data){
            if(root->left != NULL){
                return bstRecGetMax(root->left); //this func return node with Max key
            }else{
                return pred;
            }
        }
    }
}

【问题讨论】:

  • 遍历树的时候,只要保持前任..
  • 我忘了说应该递归完成
  • 真的没关系。在递归函数中添加一个名为“parent”的参数,并将当前访问的节点作为一个传递。
  • 我把我写的代码贴出来了

标签: c binary-search-tree


【解决方案1】:

如果您希望节点 N 的前任在有序遍历的意义上,有三种可能性:

  1. N 有一个左孩子。在这种情况下,前驱是 N 的左子树的最右边的元素。
  2. N 没有左孩子,并且在从根到 N的路径中至少有一步向右。在这种情况下,前导是该路径上最靠近 N 的向右步骤的源节点。
  3. N 没有左孩子,并且从根到它的路径上没有向右的步骤。在这种情况下,N 是树中的最小元素,因此它没有前任。

因此,您必须做的是跟踪最近向右步骤的来源(不一定是直接父级)作为递归搜索函数的附加参数,通过它您可以找到节点 N em>。当您到达 N 时,您将可以在 N 没有左孩子的情况下使用它,如果 N 确实有左孩子,则可以忽略它。

【讨论】:

  • 看起来差不多,@Diablo3000,但是如果你要检查 root 是否为空,那么你应该在尝试检查节点成员之前 它指向。另请注意,对该函数的初始调用需要将NULL 作为第三个参数传递;就个人而言,我会提供一个包装函数来向客户端隐藏该细节。无论如何,做测试。没有什么比彻底的测试更重要了。
  • 好的,谢谢,我会包装这个函数,很快就会测试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多