在二叉搜索树上找到大于X的第一个键

时间:2015-07-04 23:06:22

标签: c algorithm binary-search-tree

  

BST中元素的继承者是元素的继承者   按顺序遍历确定的排序顺序。找到了   当每个节点都有一个指向其父节点的指针时,将显示后继   在CLRS的算法教科书(麻省理工学院的算法导论)中   按)。

有没有办法在结构中找到大于X但没有parent的第一个值?喜欢:

typedef struct tree tree;
struct tree{
   int value;
   tree *left;
   tree *right;
};

//Function:  

tree *find_first_bigger(tree *t, int x){}  

我尝试过:

tree *find_first_bigger(tree *t, int x){
   if(t == NULL)
      return NULL;

   if((*t)->value > x)
      find_first_bigger((*t)->left, x);

   else if((*t)->value < x)
      find_first_bigger((*t)->right), x);
   else if((*t)->value == x){
      if((*t)->right != NULL) 
         return tree_first_bigger((*t)->right);
      else
         return tree;
   }
}  

通过这个例子(它使用了字母,但没有问题),如果我尝试搜索第一个大于N(它应该返回我O),但它返回我{{1 }}

Search Binary Tree

4 个答案:

答案 0 :(得分:0)

你完成了90%的工作。允许我做剩余的10%。

由于t是指向结构的指针,因此您应使用 t-&gt; left 而不是(* t) - &gt; left ,同样适用于访问正确的结构字段。

现在,只需将您的功能修改为:

将此添加为您功能的第一行

static tree* PTR=NULL;

将第二个if条件修改为

if(t->value > x)
 {
     PTR=t;
     find_first_bigger(t->left, x);
 }

如果条件为:

,则修改第二个else
else if(t->value == x)
{
  if(t->right != NULL)
     {
         t=t->right;
         while(t->left!=NULL)
            t=t->left;
         return t;
     }
  else return PTR;
}

因此正确的功能是

tree *find_first_bigger(tree *t, int x)
{
   static tree* PTR=NULL;
   if(t == NULL)
      return NULL;
   if(t->value > x)
     {
         PTR=t;
         find_first_bigger(t->left, x);
     }
   else if(t->value < x)
       find_first_bigger(t->right, x);
   else if(t->value == x)
    {
      if(t->right != NULL)
         {
             t=t->right;
             while(t->left!=NULL)
                t=t->left;
             return t;
         }
      else return PTR;
   }
}

在main函数中,如果返回的指针为NULL,则表示:密钥本身是最大的密钥。任意查询都可以随意使用。

答案 1 :(得分:0)

我还没有测试过,但是我认为它应该可以工作。让我知道是否有错。 // c ++ 11

 #include<iostream>
 using namespace std;
 struct BSTNode{
     int val;
     BSTNode* left;
     BSTNode* right;
 };


 int FindJustLarger(BSTNode*& node, int token, int sofarlarge){
    // for invalid inputs it will return intial value of sofarlarge
    // By invalid input I mean token > largest value in BST
    if(node == nullptr)
        return sofarlarge;

    else if(node->val > token){
        sofarlarge = node->val;
        return FindJustLarger(node->left, token, sofarlarge);}

    else
        return FindJustLarger(node->right, token, sofarlarge);}

int main(){
    BSTNode* head = new BSTNode{5, nullptr, nullptr};
    FindJustLarger(head, 5, NULL);
    delete head;
    return 0;}

答案 2 :(得分:-1)

您可以在代码中进行一些更改:

  • 您必须从递归调用中返回值

  • 如果未找到该值,请返回NULL。这意味着,如果NULL上的t->right == NULL返回if

  • 当向左移动时,如果在那里找不到值,则答案必须是节点本身。对于N,它是我们左转的最后一个节点:O。如果是P,答案将是T本身。

完成所有这些更改后,代码应如下所示:

tree *find_first_bigger(tree *t, int x){
   if(t == NULL)
      return NULL;

   if(t->value > x) {
      tree *answer = find_first_bigger(t->left, x);
      if (answer != NULL) 
          return answer;
      return t;
   } else if(t->value < x) {
      return find_first_bigger(t->right, x);
   } else if(t->value == x) {
      if (t->right != NULL)
          return tree_first_bigger(t->right);
      return NULL;
   }
}  

您可以找到我用来测试in this gist的完整代码。

答案 3 :(得分:-1)

在你的问题中,你似乎表明你想找出给定值的&#39; x&#39;的InOrderSuccessor()。

如果&#39; x&#39;不一定存在于树中,我们需要改变算法。给出您提供的示例和问题陈述,这里是用于在BST中查找下一个元素的代码。

关键案例是:

  • 不存在更多元素,因为&#39; x&#39;是最大的。
  • &#39; X&#39;有一个合适的孩子?
  • 是:得到x的右子树的最左边的孩子。
  • 不:回归父母。

关键的观察是,每当我们进入树中时,我们都不会更新父指针。

  tree *ptr = root;
  tree *prnt = NULL;
  while (ptr != NULL) {
      if (x == ptr->key) {
          if (ptr->right != NULL) {
              return GetLeftMostChild(ptr->right);
          } else {
              return prnt;
          }
      } else if (x > ptr->key) {
          ptr = ptr->right;
      } else {
          prnt = ptr;
          ptr = ptr->left;
      }
  }

这是leftMostChild()

的定义
tree *GetLeftMostChild(tree *n) {
    tree *ptr = n;
    while (ptr->left != NULL) {
        ptr = ptr->left;
    }
    return ptr;
}