C 在BST中查找前置程序

C 在BST中查找前置程序,c,binary-search-tree,C,Binary Search Tree,我希望在二元搜索树中递归高效地搜索前置项,而不使用父指针。 我给出树的根和某个数据(可以包含在BST中,也可以不包含在BST中)作为函数的参数 我遇到了问题,因为如果BST不包含数据,函数应该在输出中给出小于它的最大值 Node *recPredecessor(Node *root, int data, Node *pred){ if(root->key > data){ return recPredecessor(root->left, data, p

我希望在二元搜索树中递归高效地搜索前置项,而不使用父指针。 我给出树的根和某个数据(可以包含在BST中,也可以不包含在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;
            }
        }
    }
}
Node*recpreducer(Node*root,int数据,Node*pred){
如果(根->键>数据){
返回(根->左,数据,pred);
}
如果(根->键<数据){
返回(根->右,数据,根);
}
if((root==NULL)| |(root->key==data)){
if(root==NULL){
返回pred;
}
如果(根->键==数据){
如果(根->左!=NULL){
return bstrecketmax(root->left);//此函数返回具有Max键的节点
}否则{
返回pred;
}
}
}
}

如果您希望前一个节点以顺序遍历的方式连接到节点N,有三种可能性:

  • N有一个左撇子。在本例中,前置元素是N左子树的最右边元素
  • N没有左子级,并且从根到N的路径中至少有一个向右的步骤。在这种情况下,前置节点是该路径上距离N最近的向右步长的源节点
  • N没有左子级,并且从根开始沿路径没有向右的步骤。在本例中,N是树中的最小元素,因此它没有前置元素

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

    如果您希望前一个节点按顺序遍历,则有三种可能性:

  • N有一个左撇子。在本例中,前置元素是N左子树的最右边元素
  • N没有左子级,并且从根到N的路径中至少有一个向右的步骤。在这种情况下,前置节点是该路径上距离N最近的向右步长的源节点
  • N没有左子级,并且从根开始沿路径没有向右的步骤。在本例中,N是树中的最小元素,因此它没有前置元素

  • 因此,您必须做的是跟踪最近右移步骤的来源(不一定是直接父级),作为递归搜索函数的附加参数,通过该函数可以查找节点N。当你到达N时,如果N没有左子女,你就可以随时使用它,如果N确实有左子女,你可以忽略它。

    当你遍历树时,只需保留前一个。我忘了说应该递归执行它真的没关系。在递归函数中添加一个名为“parent”的参数,并将当前访问的节点作为一个节点传递。我在遍历树时发布了我编写的代码,只需保留前一个即可。我忘了说应该递归执行这真的没关系。在递归函数中添加一个名为“parent”的参数,并将当前正在访问的节点作为一个节点传递。我发布了我编写的代码@Diablo3000,看起来不错,但是如果您要检查
    root
    是否为null,那么您应该在尝试检查它指向的节点的成员之前执行此操作。还要注意,对该函数的初始调用需要传递
    NULL
    作为第三个参数;就个人而言,我会提供一个包装器函数来向客户机隐藏该细节。在任何情况下,都要进行测试。没有什么比彻底的测试更有效。是的,谢谢,我将包装此函数并很快对其进行测试。它看起来是正确的,@Diablo3000,但是如果您要检查
    root
    是否为null,那么您应该在尝试检查它指向的节点的成员之前执行此操作。还要注意,对该函数的初始调用需要传递
    NULL
    作为第三个参数;就个人而言,我会提供一个包装器函数来向客户机隐藏该细节。在任何情况下,都要进行测试。没有什么比彻底测试更好的了。是的,谢谢你,我将包装这个函数并很快进行测试。