7
votes

Comment déterminer si un arbre binaire est terminé?

Un arbre binaire complet est défini comme un arbre binaire dans lequel chaque niveau, sauf éventuellement le plus profond, est complètement rempli. Au niveau le plus profond, tous les nœuds doivent être aussi loin que possible que possible.

Je penserais qu'un simple algorithme récursif sera en mesure de savoir si un arbre binaire donné est complet, mais je ne peux pas sembler le comprendre.


1 commentaires

Veuillez vous reporter à la Stackoverflow.com/Questtions/18159884/... pour l'une des approches la plus faciles.


16 Réponses :


5
votes

Semblable à:

complete(t) = if (t==NULL) then (0,true) else { 
                  let (hl,fl)=complete(t.left)
                  let (hr,fr)=complete(t.right)                      
                  if (fl && hl==hr) then (1+h,fr)
                  else if (fr && hl==hr+1) then (1+h,false)
                  else (-1,false)
              }


4 commentaires

Cela ne fonctionnera pas pour un arbre comme celui-ci (A (B (D) (E) (E)) (C)) Remarque: (Racine (à gauche) (à droite))


La vérification peut être modifiée pour permettre une différence de hauteur de 1, mais cela donnera un résultat incorrect pour (A (B (D (H) (I)) (e)) (C (F (J) (K) (K)) (G) )))).


Je vois. La terminologie m'a confondu. "Terminé" ne signifie pas vraiment complet.


Corrigé pour la version "partiellement pleine complète du dernier niveau" de complète.



0
votes

Vous pouvez combiner trois informations des sous-arbres:

  • si le sous-arbre est complet

  • la hauteur maximale

  • La hauteur minimale (égale à la hauteur maximale ou à la hauteur maximale - 1)


0 commentaires

-1
votes

Vous pouvez dire si un arbre binaire donné est un arbre binaire complet - mieux connu sous le nom de tas binaire en veillant à ce que chaque nœud avec un enfant droit ait également un enfant à gauche. Voir ci-dessous

bool IsLeftComplete(tree)
{

  if (!tree.Right.IsEmpty && tree.Left.IsEmpty)
    //tree has a right child but no left child, therefore is not a heap
    return false;    

  if (tree.Right.IsEmpty && tree.Left.IsEmpty)  
    //no sub-trees, thus is leaf node. All leaves are complete
    return true;

  //this level is left complete, check levels below
  return IsLeftComplete(tree.Left) && IsLeftComplete(tree.Right);
}


1 commentaires

Non. Il peut y avoir un nœud qui a deux arbres complets de hauteur très différente en tant qu'enfants.



0
votes

Il peut y avoir un algorithme possible que je ressens résoudrait ce problème. Considérez l'arborescence:

Level 0:    a  
Level 1:  b   c  
Level 2: d e f g  
  • Nous utilisons la première traverse de la largeur. P> Li>

  • Pour chaque élément en cours de file d'attente, nous devons faire trois chèques pour: P>

    1. S'il y a un enfant unique ou aucun enfant terminé; sinon, vérifiez 2. li>
    2. S'il existe des deux enfants définir un drapeau global = true.
      1. Définissez des indicateurs pour chaque nœud de la file d'attente comme true: drapeau [b] = drapeau [c] = true. li>
      2. Vérifiez que chaque entrée s'ils ont laissé n enfant droit N puis définissez les indicateurs ou les réinitialisez-les sur FALSE. LI>
      3. (Dequue) Si (Queue_empty ())
        Comparez tous les drapeaux de nods [] ... Si tout TRUE Global_Flag = True Else Global_Flag = False. Li>
      4. Si Global_Flag = True Go pour procéder avec le niveau suivant dans la largeur d'abord d'une première trersharse Terminez LI> ol> li> ol> li> ul>

        Avantage: l'arbre entier ne peut pas être traversé
        Sur-tête: maintenir les entrées d'indicateur p> p>


0 commentaires

0
votes

Vous pouvez le faire récursivement en comparant les hauteurs des enfants de chaque noeud. Il peut y avoir au plus un noeud où l'enfant gauche a une hauteur exacte exactement d'une plus grande que le bon enfant; Tous les autres nœuds doivent être parfaitement équilibrés.


2 commentaires

La hauteur étant définie comme la distance du nœud feuille le plus proche? Noeud de la feuille la plus éloignée?


@Null Set: La hauteur est la distance entre le nœud actuel sur la feuille la plus profonde parmi ses descendants.



2
votes
//Helper function

int depth (struct tree * n)
{
   int ld,rd;

   if (n == NULL) return 0;

   ld=depth(n->left);
   ld=depth(n->right);

   if (ld>rd)
      return (1+ld);
   else
      return (1+rd);

}


//Core function

int isComplete (struct tree * n)
{
   int ld,rd;

   if (n == NULL) return TRUE;

   ld=depth(n->left);
   rd=depth(n->right);

   return(ld==rd && isComplete(n->left) && isComplete(n->right));

}

1 commentaires

Ce n'est pas la définition de l'arbre binaire complet que @akshay a demandé. Vous mettez en œuvre l'arbre parfait »



4
votes

La procédure la plus simple est la suivante:

  1. Trouvez la profondeur de l'arbre (algorithme simple).
  2. comptez le nombre de nœuds dans un arborescence (en parcourant et en augmentant le compteur par une sur la visite de tout nœud).
  3. pour un arbre binaire complet de niveau d le nombre de nœuds est égal à pow (2, D + 1) -1 . .

    Si l'état de la condition satisfaire, est un arbre binaire complet, sinon pas.

    C'est un algorithme simple et la transformant en code de travail ne devrait pas être un problème si vous êtes assez bon codeur.


1 commentaires

Mais cela ne fonctionnera pas si le dernier niveau n'est pas complètement plein.



-1
votes
int height (node* tree, int *max, int *min) {

  int lh = 0 , rh = 0 ;
  if ( tree == NULL )
    return 0;
  lh = height (tree->left,max,min) ;
  rh = height (tree->right,max,min) ;
  *max = ((lh>rh) ? lh : rh) + 1 ;
  *min = ((lh>rh) ? rh : lh) + 1 ;
  return *max ;
}

void isCompleteUtil (node* tree, int height, int* finish, int *complete) {
  int lh, rh ;
  if ( tree == NULL )
    return ;
  if ( height == 2 ) {
    if ( *finish ) {
      if ( !*complete )
        return;
      if ( tree->left || tree->right )
        *complete = 0 ;
      return ;
    }
    if ( tree->left == NULL && tree->right != NULL ) {
      *complete = 0 ;
      *finish = 1 ;
    }
    else if ( tree->left == NULL && tree->right == NULL )
      *finish = 1 ;
    return ;
  }
  isCompleteUtil ( tree->left, height-1, finish, complete ) ;
  isCompleteUtil ( tree->right, height-1, finish, complete ) ;
}

int isComplete (node* tree) {
  int max, min, finish=0, complete = 1 ;
  height (tree, &max, &min) ;
  if ( (max-min) >= 2 )
    return 0 ;
  isCompleteUtil (tree, max, &finish, &complete) ;
  return complete ;
}

0 commentaires

0
votes

Le code suivant traite simplement tous les cas possibles. La hauteur de l'arbre est obtenue en cours de route pour éviter une autre récursion.

enum CompleteType
{
    kNotComplete = 0,
    kComplete = 1, // Complete but not full
    kFull = 2,
    kEmpty = 3
};

CompleteType isTreeComplete(Node* node, int* height)
{
    if (node == NULL)
    {
        *height = 0;
        return kEmpty;
    }

    int leftHeight, rightHeight;

    CompleteType leftCompleteType = isTreeComplete(node->left, &leftHeight);
    CompleteType rightCompleteType = isTreeComplete(node->right, &rightHeight);

    *height = max(leftHeight, rightHeight) + 1;

    // Straight forwardly treat all possible cases
    if (leftCompleteType == kComplete && 
        rightCompleteType == kEmpty &&
        leftHeight == rightHeight + 1)
        return kComplete;

    if (leftCompleteType == Full)
    {
        if (rightCompleteType == kEmpty && leftHeight == rightHeight + 1)
            return kComplete;
        if (leftHeight == rightHeight)
        {
            if (rightCompleteType == kComplete)
                return kComplete;
            if (rightCompleteType == kFull)
                return kFull;
        }
    }

    if (leftCompleteType == kEmpty && rightCompleteType == kEmpty)
        return kFull;

    return kNotComplete;
}

bool isTreeComplete(Node* node)
{
    int height;
    return (isTreeComplete(node, &height) != kNotComplete);
}


0 commentaires

0
votes

Vous pouvez également résoudre ce problème en utilisant la traversée de commande de commande. La procédure est la suivante:

  1. Stockez l'élément de données des nœuds rencontrés dans un vecteur
  2. Si le nœud est NULL, puis stockez un numéro spécial (INT_MIN)
  3. Gardez une trace du dernier nœud non nul visité - LenteTry
  4. Maintenant, traversez le vecteur jusqu'à l'autre détenteur. Si vous rencontrez jamais INT_MIN, l'arborescence n'est pas terminée. Sinon c'est un arbre binaire complet.

    Voici un code C ++:

    mon nœud d'arbre est: xxx


0 commentaires

0
votes
private static boolean isCompleteBinaryTree(TreeNode root) {

if (root == null) {
    return false;
} else {
    boolean completeFlag = false;
    List<TreeNode> list = new ArrayList<TreeNode>();
    list.add(root);
    while (!list.isEmpty()) {
        TreeNode element = list.remove(0);
        if (element.left != null) {
            if (completeFlag) {
                return false;
            }
        list.add(element.left);
        } else {
            completeFlag = true;
        }
        if (element.right != null) {
            if (completeFlag) {
                return false;
            }
        list.add(element.right);
        } else {
            completeFlag = true;
        }
    }
        return true;
    }
}
Reference:
Check the following link for a detailed explanation
http://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-complete-tree-or-not/

0 commentaires

0
votes

Merci pour le pseudo code de @jonathan Graehl. Je l'ai mis en œuvre à Java. Je l'ai testé contre la version itérative. Cela fonctionne comme un charme!

public static boolean isCompleteBinaryTreeRec(TreeNode root){
//      Pair notComplete = new Pair(-1, false);
//      return !isCompleteBinaryTreeSubRec(root).equalsTo(notComplete);
    return isCompleteBinaryTreeSubRec(root).height != -1;
}

public static boolean isPerfectBinaryTreeRec(TreeNode root){
    return isCompleteBinaryTreeSubRec(root).isFull;
}

public static Pair isCompleteBinaryTreeSubRec(TreeNode root){
    if(root == null){
        return new Pair(0, true);
    }

    Pair left = isCompleteBinaryTreeSubRec(root.left);
    Pair right = isCompleteBinaryTreeSubRec(root.right);

    if(left.isFull && left.height==right.height){
        return new Pair(1+left.height, right.isFull);
    }

    if(right.isFull && left.height==right.height+1){
        return new Pair(1+left.height, false);
    }

    return new Pair(-1, false);
}

private static class Pair{
    int height;         
    boolean isFull;     

    public Pair(int height, boolean isFull) {
        this.height = height;
        this.isFull = isFull;
    }

    public boolean equalsTo(Pair obj){
        return this.height==obj.height && this.isFull==obj.isFull;
    }
}


0 commentaires

0
votes

Voici un code C pour vérifier si l'arborescence binaire est terminée: xxx

la manière dont il fonctionne est:

  • Si la profondeur de la sous-arbre gauche est la même que la profondeur du sous-arbre de droite, il retourne la profondeur de l'Hireearchy.

  • Si la profondeur de la sous-arbre gauche est une plus grande que la profondeur du sous-arbre droit, il retourne la profondeur de la sous-étude droite en haut de l'hirarchie et active le drapeau.

  • S'il trouve que la profondeur de la sous-arbre gauche et du sous-arbre et du drapeau droit est déjà définie, il renvoie -1 up la hiérarchie.

  • à la fin, si la fonction renvoie -1, ce n'est pas le sous-arbre complet, sinon la valeur renvoyée est la profondeur minimale de l'arborescence.


0 commentaires

1
votes

pour qu'un arbre soit complet

hauteur (gauche) == hauteur (à droite) ou Hauteur (à gauche) == 1 + hauteur (droite) xxx


0 commentaires

0
votes
bool isComplete (struct Node* root){
    if(root==NULL)
    return true;                  // Recur for left and right subtree 
    bool flag=false;
    int option1=height(root->left);
    int option2=height(root->right);
    if(option1==option2||option1==option2+1)
    flag=true;
    return flag&&isComplete(root->left)&&isComplete(root->right);
    }
please consider as a correct answer if you found useful.

0 commentaires

0
votes

Tout d'abord, comptez le nombre de nœuds dans l'arbre binaire. Écrivez une fonction récursive. Si le nœud reçu est NULL, cela revient vrai. Si l'index du nœud est supérieur ou égal de nœuds, l'arborescence n'est pas binaire. Si aucun de ces deux est arrivé, vérifiez les sous-arbres gauche et droit. import java.util.linkedlist; import java.util.queue; xxx

J'espère que cela aide.


0 commentaires