Si un Arbre Binaire est un Arbre de Recherche Binaire [dupliquer]
cette question a déjà une réponse ici:
- Comment valider un arbre de recherche binaire? 27 Réponses
Aujourd'hui j'ai eu une interview où on m'a demandé d'écrire un programme qui prend un arbre binaire et retourne vrai si c'est aussi un arbre de recherche binaire autrement faux.
Mon Approach1: Effectuer une traversée de l'ordre et de stocker les éléments de O(n) fois. Maintenant, scannez le tableau / la liste des éléments et vérifiez si l'élément à l'index i th est plus grand que l'élément à l'index (i+1) th . Si une telle condition est rencontrée, retourner false et sortir de la boucle. (Cela prend O(n) le temps). À la fin return true.
mais ce monsieur voulait que je fournisse une solution efficace. J'ai essayé, mais J'ai échoué, parce que pour trouver si c'est un BST je dois vérifier chaque noeud.
de plus, il me montrait du doigt pour penser à la récursion. Mon approche 2: un BT est un BST si pour n'importe quel noeud N->gauche est droite > N , et le successeur dans l'ordre du noeud de gauche de N est inférieur à N et le successeur dans l'ordre du noeud de droite de N est plus grand que N et les sous-arbres de gauche et de droite sont BSTs.
mais cela va être compliqué et le temps de course ne semble pas pour être bon. S'il vous plaît aider si vous connaissez une solution optimale.
7 réponses
c'est un problème assez bien connu avec la réponse suivante:
public boolean isValid(Node root) {
return isValidBST(root, Integer.MIN_VALUE,
Integer.MAX_VALUE);
}
private boolean isValidBST(Node node, int l, int h) {
if(node == null)
return true;
return node.value > l
&& node.value < h
&& isValidBST(node.left, l, node.value)
&& isValidBST(node.right, node.value, h);
}
l'appel récursif fait en sorte que les noeuds subtree soient à la portée de ses ancêtres, ce qui est important. La complexité du temps d'exécution sera O (n) puisque chaque noeud est examiné une fois.
l'autre solution serait de faire une traversée ordonnée et de vérifier si la séquence est triée, d'autant plus que vous savez déjà qu'un arbre binaire est fourni comme entrée.
la réponse fournie par @Dhruv est bonne. En plus de cela, Voici une autre solution qui fonctionne en O (n) temps.
Nous devons garder une trace du noeud précédent dans cette approche. Dans chaque appel récursif, nous vérifions les données du noeud précédent avec les données du noeud actuel. Si les données du noeud courant sont inférieures aux précédentes, nous retournons false
int isBST(node* root) {
static node* prev = NULL;
if(root==NULL)
return 1;
if(!isBST(root->left))
return 0;
if(prev!=NULL && root->data<=prev->data)
return 0;
prev = root;
return isBST(root->right);
}
boolean b = new Sample().isBinarySearchTree(n1, Integer.MIN_VALUE, Integer.MAX_VALUE);
.......
.......
.......
public boolean isBinarySearchTree(TreeNode node, int min, int max){
if(node == null){
return true;
}
boolean left = isBinarySearchTree(node.getLeft(), min, node.getValue());
boolean right = isBinarySearchTree(node.getRight(), node.getValue(), max);
return left && right && (node.getValue()<max) && (node.getValue()>=min);
}
nous vous invitons à nous faire part de vos commentaires. Grâce.
je pense que la deuxième approche est juste. L'arbre peut être parcouru de manière récursive. Sur chaque itération les limites inférieures et supérieures du sous-arbre courant peuvent être stockées. Si nous voulons vérifier subtree avec la racine x, et les limites pour le subtree sont l et h, alors tout ce que nous avons besoin est de vérifier que l <= x <= h et de vérifier le subtree gauche avec les limites l et x, et la droite avec les limites x et H.
cela aura une(n) complexité, parce que nous partons de la racine et de chaque le noeud n'est vérifié qu'une fois en tant que racine d'un certain sous-arbre. En outre, nous avons besoin de mémoire O(h) pour les appels récursifs, où h est la hauteur de l'arbre.
il y a quelques exemples ci-dessus utilisant INTEGER.MAX ET MIN Je ne vois pas de raison de les dépasser et la signification de celui-ci, corrigez-moi si je me trompe ou expliquez-moi la raison.
plus sur l'arbre de recherche binaire peut avoir des objets qui sont comparés par la méthode compareTo ou Coperator.. ( donc entière.MIN et entier.MAX dont fit sur ce modèle) J'écris un code où il retourne vrai ou faux on a appeler (root_node,vrai) et il retournera true si c'est un bst sinon false
void boolean isBSt( node root_node, boolean passed_root)
{
if ( node==null){
if ( passed_root)
return false;
// you have passed null pointer as
//root of the tree , since there is no
// valid start point we can throw an exception or return false
return true;
}
if( node.right !=null )
if ( node.right.data <= node.data)
return false;
if ( node.left !=null )
if ! ( node.left.data <= node.data)
return false;
return ( isBST( node.right , false) && isBST( node.left, false ) )
}
Regardez cette solution: http://preparefortechinterview.blogspot.com/2013/09/am-i-bst.html
il explique différentes façons et vous donne une méthode générique et efficace aussi. Espérons que cela aide.
Voici une autre Solution qui utilise 2 fonctions d'aide pour calculer pour chaque noeud la valeur min et max dans le sous-arbre en utilisant la fonction d'aide minValue et maxValue
int isBST(struct node* node)
{
if (node == NULL)
return(true);
/* false if the max of the left is > than us */
if (node->left!=NULL && maxValue(node->left) > node->data)
return(false);
/* false if the min of the right is <= than us */
if (node->right!=NULL && minValue(node->right) < node->data)
return(false);
/* false if, recursively, the left or right is not a BST */
if (!isBST(node->left) || !isBST(node->right))
return(false);
/* passing all that, it's a BST */
return(true);
}