La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Les arbres binaires. Arbre binaire Les arbres binaires se définissent de façon récursive. Un arbre binaire T est une relation définie sur un ensemble.

Présentations similaires


Présentation au sujet: "Les arbres binaires. Arbre binaire Les arbres binaires se définissent de façon récursive. Un arbre binaire T est une relation définie sur un ensemble."— Transcription de la présentation:

1 Les arbres binaires

2 Arbre binaire Les arbres binaires se définissent de façon récursive. Un arbre binaire T est une relation définie sur un ensemble fini de nœuds et qui satisfait une des deux conditions suivantes: lensemble ne contient aucun nœud, ou lensemble est constitué de trois sous-ensembles disjoints de nœuds: –un nœud unique appelé racine –un arbre binaire appelé sous-arbre de gauche –un arbre binaire appelé sous-arbre de droite.

3 Exemple darbre binaire Notation: Noeud,enfant, arête, parent, ancêtre, descendant, chemin, profondeur, hauteur, niveau, feuille, noeud interne, sous-arbre.

4 Arbre binaire plein et complet Arbre binaire plein: Chaque noeud est soit une feuille ou possède exactement deux enfants Arbre binaire complet: Si la hauteur de larbre est d, alors tous les niveau sont complets, sauf possiblement le dernier. Les feuilles au dernier niveau sont complètement à gauche.

5 Arbre binaire plein (1) Théorème: Dans un arbre binaire plein, le nombre de feuilles est un de plus que le nombre de noeuds internes. Preuve (par induction mathématique sur le nombre de noeuds internes): Base: Sil y a un seul noeud interne alors le nombre de feuilles est 2. Hypothèse dinduction: Supposons quun arbre binaire plein avec n-1 noeuds internes contient n feuilles.

6 Arbre binaire plein (2) Pas dinduction: Soit T, un arbre binaire avec n noeuds internes. Il existe un nœud interne P dont les deux enfants (P 1 et P 2 ) sont des feuilles. Soit T larbre obtenu en enlevant P 1 et P 2 de T. Donc, T contient n-1 nœuds internes Par hypothèse dinduction, T est un arbre binaire plein avec n feuilles

7 Arbre binaire plein (3) Toutes les feuilles de T (sauf P) sont aussi des feuilles de T. P est une feuille de T mais pas de T Le nombre de feuille dans T est donc: nombre de feuilles dans T - le nœud P + les deux feuilles P 1 et P 2 Donc T contient n+1 feuilles.

8 Classe abstraite template class BinNode { public: virtual Elem& val() = 0; virtual void setVal(const Elem&) = 0; virtual BinNode* left() const = 0; virtual void setLeft(BinNode*) = 0; virtual BinNode* right() const = 0; virtual void setRight(BinNode*) = 0; virtual bool isLeaf() = 0; };

9 Classe avec pointeurs (1) // Binary tree node class template class BinNodePtr : public BinNode { private: Elem it; // La valeur du noeud BinNodePtr* lc; // pointe à gauche BinNodePtr* rc; // pointe à droite public: BinNodePtr() { lc = rc = NULL; } BinNodePtr(Elem e, BinNodePtr* l =NULL, BinNodePtr* r =NULL) { it = e; lc = l; rc = r; }

10 Classe avec pointeurs (2) Elem& val() { return it; } void setVal(const Elem& e) { it = e; } BinNode * left() const { return lc; } void setLeft(BinNode * b) { lc = (BinNodePtr*)b; } BinNode * right() const { return rc; } void setRight(BinNode * b) { rc = (BinNodePtr*)b; } bool isLeaf() { return (lc == NULL) && (rc == NULL); } };

11 Parcours (1) Une méthode permettant de visiter tous les nœuds dun arbre dans un ordre quelconque est appelée un parcours (ou une fouille). Un parcours où chaque nœud est visité exactement une fois est appelé une énumération.

12 Parcours (2) Parcours en préordre: on visite un nœud avant de visiter ses enfants. Parcours en postordre: on visite un nœud apès avoir visiter ses enfants. Parcours en ordre: on visite dabord le sous-arbre de gauche, puis la racine et enfin le sous-arbre de droite.

13 Parcours (3) template void preorder(BinNode * subroot) { if (subroot == NULL) return; visit(subroot); // Faire une action preorder(subroot->left()); preorder(subroot->right()); }

14 Exemple de parcours // Retourne le nombre de nœuds dans larbre template int count(BinNode * subroot) { if (subroot == NULL) return 0; // Rien à compter return 1 + count(subroot->left()) + count(subroot->right()); }

15 Implémentation (1)

16 Implémentation (2)

17 Implémentation avec union(1) enum Nodetype {leaf, internal}; class VarBinNode { // Nœud générique public: Nodetype mytype; // Type de nœud union { struct { // Nœud interne VarBinNode* left; VarBinNode* right; Operator opx; } intl; Operand var; // Feuille };

18 Implémentation avec union(2) // Constructeur pour les feuilles VarBinNode(const Operand& val) { mytype = leaf; var = val; } // Constructeur pour les nœuds internes VarBinNode(const Operator& op, VarBinNode* l, VarBinNode* r) { mytype = internal; intl.opx = op; intl.left = l; intl.right = r; } bool isLeaf() { return mytype == leaf; } VarBinNode* leftchild() { return intl.left; } VarBinNode* rightchild() { return intl.right; } };

19 Implémentation avec union(3) // Parcours en préordre void traverse(VarBinNode* subroot) { if (subroot == NULL) return; if (subroot->isLeaf()) cout << Feuille: var << endl; else { cout << Nœud interne: intl.opx << endl; traverse(subroot->leftchild()); traverse(subroot->rightchild()); }

20 Héritage (1) class VarBinNode { // Classe abstraite public: virtual bool isLeaf() = 0; }; // Feuille class LeafNode : public VarBinNode { private: Operand var; public: LeafNode(const Operand& val) { var = val; } // Constructor bool isLeaf() { return true; } Operand value() { return var; } };

21 Héritage (2) // Nœud interne class IntlNode : public VarBinNode { private: VarBinNode* left; VarBinNode* right; Operator opx; public: IntlNode(const Operator& op, VarBinNode* l, VarBinNode* r) { opx = op; left = l; right = r; } bool isLeaf() { return false; } VarBinNode* leftchild() { return left; } VarBinNode* rightchild() { return right; } Operator value() { return opx; } };

22 Héritage (3) // Parcours en préordre void traverse(VarBinNode *subroot) { if (subroot == NULL) return; if (subroot->isLeaf()) // Feuille cout << "Leaf: " value() << endl; else { // Nœud interne cout << "Internal: " value() << endl; traverse(((IntlNode*)subroot)->leftchild()); traverse(((IntlNode*)subroot)->rightchild()); }

23 Espace mémoire (1) Du théorème sur les arbre binaire plein: La moitié des pointeurs sont null. If leaves store only data, then overhead depends on whether the tree is full. Ex: Tous les nœuds sont similaires avec deux pointeurs aux enfants. Espace total requis: (2p + d)n Espace pour pointeurs: 2pn Si p = d, alors lespace pour pointeurs est 2p/(2p + d) = 2/3.

24 Espace mémoire(2) Si on élimine les pointeurs aux feuilles, la fraction despace perdu est alors: Ce qui fait 1/2 si p = d. Remarque: De lespace supplémentaire est tout de même nécessaire afin de pouvoir différencier une feuille dun nœud interne.

25 Implémentation avec tableau (1) Position Parent Fils de Gauche Fils de Droite Frère de gauche Frère de droite

26 Implémentation avec tableau(2) Parent (r) = (r-1)/2 si r 0 Leftchild(r) = 2r+1 si 2r+1 < n Rightchild(r) = 2r+2 si 2r+2 < n Leftsibling(r) = r-1 si r>0 est pair Rightsibling(r) = r+1 si r n est impair


Télécharger ppt "Les arbres binaires. Arbre binaire Les arbres binaires se définissent de façon récursive. Un arbre binaire T est une relation définie sur un ensemble."

Présentations similaires


Annonces Google