Pour trouver le plus grand élément plus petit que K dans un BST

voix
17

Étant donné un arbre de recherche binaire et un entier K, je voudrais trouver le plus grand élément inférieur à K.

Dans l'arborescence ci-dessous,

for K = 13, result = 12
for K = 10, result = 8
for K = 1 (or) 2, result = -1

      10

  5       12

2   8   11  14

J'ai essayé la logique ci-dessous. Mais est-il une meilleure façon de le faire?

int findNum(node* node, int K)
{
        if(node == NULL)
        {
                return -1;
        }
        else if(K <= node->data)
        {
                return findNum(node->left,K);
        }
        else if(K > node->data)
        {
                int t = findNum(node->right,K);
                return t > node->data ? t : node->data;
        }

        return -1;
}
Créé 13/06/2011 à 19:22
source utilisateur
Dans d'autres langues...                            


5 réponses

voix
1

Je suggère que vous marchez à travers le code dans votre mise en œuvre locale de jeu :: UPPER_BOUND à titre indicatif. Ce n'est pas la solution à votre problème exact, mais très proche.

En général, dans la vraie vie, la plupart de ces problèmes ne doivent pas nécessairement être résolu dans votre propre code. STL peut faire beaucoup de tâches courantes pour vous. Il est utile de savoir comment les résoudre bien sûr, d'où l'épreuve.

Créé 13/06/2011 à 19:29
source utilisateur

voix
3

Je crois à l' utilisation des installations de la bibliothèque standard. Ainsi, ma solution utilise std::set. :-)

int largest_num_smaller_than(std::set<int> const& set, int num)
{
    std::set<int>::const_iterator lb(set.lower_bound(num));
    return lb == set.begin() ? -1 : *--lb;
}
Créé 13/06/2011 à 19:33
source utilisateur

voix
19

C'est O (log n), qui est le minimum. Cependant, vous pouvez améliorer l'efficacité ( ce qui semble être la principale chose ces enquêteurs se soucient) et éliminer la possibilité de débordement de pile (Tada!) En éliminant récursion arrière, transformer cela en une boucle. En outre, votre code ne fonctionne pas si l'arbre contient des nombres négatifs ... si vous voulez dire non négatifs entiers, vous devriez le dire, mais si l'intervieweur a juste dit « entiers » , vous devez alors le code légèrement différent et une API différente. (Vous pouvez garder la même signature de la fonction , mais revenir K au lieu de -1 en cas d' échec.)

Par exemple, comme cela est une question d'entrevue, la mise en œuvre en appelant une fonction de bibliothèque raconterait la plupart des enquêteurs que vous êtes un ou smartass manque le point de ou ne savent pas comment le résoudre. Ne pas déranger avec ce genre de chose, juste arriver à travailler sur ce que vous savez que l'intervieweur veut.

Voici une mise en œuvre:

// Return the greatest int < K in tree, or K if none.
int findNum (Node* tree, int K)
{
    int val = K;

    while( tree )
        if( tree->data >= K )
            tree = tree->left;
        else{
            val = tree->data; 
            tree = tree->right;
        }

    return val;
}
Créé 13/06/2011 à 20:25
source utilisateur

voix
5

Je pense que l'idée est ici pour enregistrer le dernier nœud après que vous passez à la sous-arbre droit. Par conséquent, le code sera (a été mis à jour)

int findNum (Node *node, int K)
{
    Node* last_right_move = NULL;

    while (node)
    {
        if (K<=node->data)
            node = node->left;
        else
        {
            last_right_move = node;
            node = node->right;
        }
    }

    if (last_right_move)
        return last_right_move->data;
    else
        return NOT_FOUND;  // defined previously. (-1 may conflict with negative number)
}
Créé 14/06/2011 à 03:06
source utilisateur

voix
1

Ce que la première réponse a dit, et voici la logique derrière pourquoi il ne peut pas faire mieux que O (log n). Vous recherchez le plus grand nombre inférieur à K. est assez proche d'appeler BST-recherche / get.

Bien que votre algorithme original semble assez bon, je pense que ce serait plus rapide:

    int findNum (node root, int K) {
        if(root == null) return -1;

        if(K > root.val) { 
           if(root.right != null) return findNum(root.right, K);               
           else return root.val; 
        }

        return findNum(root.left, K); //look in left subtree

    }
Créé 27/07/2011 à 11:11
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more