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. P>
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. p>
16 Réponses :
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) }
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.
Vous pouvez combiner trois informations des sous-arbres: P>
si le sous-arbre est complet p> li>
la hauteur maximale p> li>
La hauteur minimale (égale à la hauteur maximale ou à la hauteur maximale - 1) p> li> ul>
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); }
Non. Il peut y avoir un nœud qui a deux arbres complets de hauteur très différente en tant qu'enfants.
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>
Avantage: l'arbre entier ne peut pas être traversé
Sur-tête: maintenir les entrées d'indicateur p> p>
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. P>
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.
//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)); }
Ce n'est pas la définition de l'arbre binaire complet que @akshay a demandé. Vous mettez en œuvre l'arbre parfait »
La procédure la plus simple est la suivante: p>
Si l'état de la condition satisfaire, est un arbre binaire complet, sinon pas. p>
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. P>
Mais cela ne fonctionnera pas si le dernier niveau n'est pas complètement plein.
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 ; }
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); }
Vous pouvez également résoudre ce problème en utilisant la traversée de commande de commande. La procédure est la suivante:
Voici un code C ++: p>
mon nœud d'arbre est: p>
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/
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; } }
Voici un code C pour vérifier si l'arborescence binaire est terminée: la manière dont il fonctionne est: p> 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. P> Li>
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. P> li>
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. p> li>
à 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. p> li>
ul> p>
pour qu'un arbre soit complet
hauteur (gauche) == hauteur (à droite) ou Hauteur (à gauche) == 1 + hauteur (droite) p> blockQuote>
xxx pré> p>
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.
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; J'espère que cela aide. p> p>
Veuillez vous reporter à la Stackoverflow.com/Questtions/18159884/... pour l'une des approches la plus faciles.