• Aucun résultat trouvé

Conception de structures de donn´ees

N/A
N/A
Protected

Academic year: 2022

Partager "Conception de structures de donn´ees"

Copied!
48
0
0

Texte intégral

(1)

Conception de structures de donn´ ees

Cours 6 Arbres binaires

22 avril 2013

(2)

Pourquoi les arbres ?

(3)

Pourquoi les arbres ?

Structure de donn´ees omnipr´esente en Informatique :

structure naturelle: arbre de d´ecision, tournoi, g´en´ealogie, arborescence des r´epertoires, expressions arithm´etiques, ...

enalgorithmique du texte (Huffamn, prefix-trees) :

compression, recherche de motifs, d´etection de r´ep´etitions, ...

eng´eom´etriealgorithmique (quadtrees, octrees, KD-trees, arbres rouge-noir, ...) ;

enlinguistique et en compilation(arbres syntaxiques) ; pour la gestion du cache, les bases de donn´ees, les syst`emes de fichiers, ... (B-trees,).

(4)

D´ efinition des arbres BINAIRES

Unarbre binaire est une structure permettant de stocker une collection de donn´ees de mˆeme type.

D´efinition r´ecursive : un arbre binaire est : soit vide,

soit unnoeudcontenant une donn´ee et ayant2 fils(gaucheet droit) qui sont eux-mˆemes des arbres binaires.

L’espace m´emoire utilis´e par un arbre n’est pas contigu.

Lataille d’un arbre est inconnue `a priori ;

Unarbre binaire est constitu´e denoeuds qui sont li´es entre eux par des pointeurs. On ne peut acc´eder directement qu’au 1er ´el´ement (laracine) de l’arbre.

Pouracc´eder `a un ´el´ement quelconqued’un arbre , il faut descendre dans l’arbrejusqu’`a cet ´el´ement.

(5)

Repr´ esentation graphique d’un arbre binaire

3

1 8

1 29 170

2 48

(6)

Arbres binaires r´ ecursifs

(7)

Type abstrait : BTree

typedef ... BTree;

BTree makeEmptyBTree(void); // renvoie un arbre vide int isEmptyBTree(BTree bt); // teste si l’arbre est vide

BTree makeNode(Element e, Btree l, Btree r);

// renvoie un arbre de racine e ayant l et r pour fils gauche et droit Element root(BTree bt); // renvoie l’´el´ement `a la racine de l’arbre BTree leftChild(BTree bt); // renvoie le fils gauche de l’arbre BTree rightChild(BTree bt); // renvoie le fils droit de l’arbre

BTree makeLeaf(Element e); // renvoie une feuille contenant l’´el´ement e int isLeaf(BTree bt); // teste si bt est une feuille

(8)

Ecrire une fonction r´ ´ ecursive sur les arbres.

Fonction r´ecursive fonctionRecsur une arbre (bt) : Cas de base :

isEmptyBTree(bt) /* arbre vide */

isLeaf(bt) /* arbre r´eduit `a une feuille */

Cas g´en´eral (r´ecursif) :r´esoudre le probl`eme sur des arbres plus petits (les sous-arbres gauche et droit) et combiner les solutions.

fonctionRec(leftChild(bt)) fonctionRec(rightChild(bt))

(9)

Exemples

Calculer la taille (nombre de noeuds) de l’arbre ; Lib´erer l’espace m´emoire occup´e par l’arbre ; Afficher l’arbre ;

Renvoyer la liste des feuilles de l’arbre ;

Calculer la hauteur, la somme des ´el´ements, la longueur de cheminement, le nombre de Strahler ...

Compter le nombre de noeuds (ou de feuilles) `a hauteurk, Tester l’´egalit´e, l’isomorphisme, l’inclusion de 2 arbres, ...

Fabriquer une copie ou le miroir d’un arbre, ...

Chercher un ´el´ement quelconque, le min (ou max), le

(10)

Les fonctions size et freeBTree

int size(BTree bt){

if(isEmptyBTree(bt)) return 0;

else return 1+size(leftChild(bt))+size(rightChild(bt));

}

void freeBTreeRec(BTree bt){ /* fonction r´ecursive */

if(!isEmptyBTree(bt)){

BTree l=leftChild(bt); /* liens vers les fils */

BTree r=rightChild(bt);

freeNode(bt); /* lib´erer le noeud */

freeBTreeRec(l); /* lib´erer les fils r´ecursivement */

freeBTreeRec(r);

} }

(11)

La fonction printBTree

void shift(int n){

int i;

for(i = 0;i < n;i++) printf("\t");

}

void printBTree(BTree bt, int level){

if ( !isEmptyBTree(bt) ) {

printBTree( rightChild(bt), level+1 );

shift(level);

printf("%d\n", root(bt));

printBTree( leftChild(bt), level+1 );

}

(12)

La fonction listOfLeaves

/* concat´enation de 2 listes */

Rlist append(Rlist l1, Rlist l2){ ... }

Rlist listOfLeaves(BTree bt){

if( isEmptyBTree(bt) ) return newEmptyRlist();

else

if( isLeaf(bt) )

return cons( root(bt) , newEmptyRlist() );

else{

Rlist ll=listOfLeaves( leftChild(bt) );

Rlist lr=listOfLeaves( rightChild(bt) );

} return append( ll , lr );

}

(13)

Parcourir un arbre en profondeur

La structure d’arbre n’imposepas un ordre totalsur les

´el´ements, or on voudrait avoir un ordre sur ces ´el´ements.

Pour cela, on fixe unem´ethode de parcours de l’arbre qui trie les ´el´ementspar orde de visite.

11

8 7

10

1 5

0 6 2

9

3

(14)

Parcourir un arbre en profondeur

La structure d’arbre n’imposepas un ordre totalsur les

´el´ements, or on voudrait avoir un ordre sur ces ´el´ements.

Pour cela, on fixe unem´ethode de parcours de l’arbre qui trie les ´el´ementspar orde de visite.

11

8 7

10

1 5

0 6 2

9

3

(15)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(16)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(17)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(18)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(19)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(20)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(21)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(22)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(23)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(24)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(25)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(26)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(27)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(28)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(29)

Parcours pr´ efixe (la racine en 1er)

11

8 7

10

1 5

0 6 2

9

3

(30)

Parcours infixe (la racine au milieu)

11

8 7

10

1 5

0 6 2

9

3

(31)

Parcours infixe (la racine au milieu)

11

8 7

10

1 5

0 6 2

9

3

(32)

Parcours postfixe (la racine en dernier)

11

8 7

10

1 5

0 6 2

9

3

(33)

Parcours postfixe (la racine en dernier)

11

8 7

10

1 5

0 6 2

9

3

(34)

Les 3 fonctions de parcours

void printPrefixOrder(BTree bt){

if(!isEmptyBTree(bt)){

printf("%d ",root(bt));

printPrefixOrder(leftChild(bt));

printPrefixOrder(rightChild(bt));

} }

void printInfixOrder(BTree bt){

if(!isEmptyBTree(bt)){

printInfixOrder(leftChild(bt));

printf("%d ",root(bt));

printInfixOrder(rightChild(bt));

} }

void printPostfixOrder(BTree bt){ ... }

(35)

Arbres binaires en C

(36)

D´ efinition d’un arbre binaire en C

arbre vide:

3

1 8

1 29 170

arbre contenant 8 éléments

(37)

D´ efinition d’un arbre binaire en C (suite)

typedef int Element;

typedef struct node{

Element elem;

struct node *left;

struct node *right;

}Node;

typedef Node *BTree;

BTree makeEmptyBTree(void){

return (BTree)NULL;

}

int isEmptyBTree(BTree bt){

(38)

D´ efinition d’un arbre binaire en C (suite)

BTree makeNode(Element e, BTree l, BTree r){

BTree new;

if ((new=(BTree)malloc(sizeof(Node)))==NULL) erreur("Allocation rat´ee!");

new->elem=e;

new->left=l;

new->right=r;

return new;

}

BTree makeLeaf(Element e){

return makeNode(e,makeEmptyBTree(),makeEmptyBTree());

}

Element root(BTree bt){

if(isEmptyBTree(bt))

erreur("Pas de noeud `a la racine!");

(39)

D´ efinition d’un arbre binaire en C (suite)

BTree leftChild(BTree bt){

if(isEmptyBTree(bt)) erreur("Pas de fils gauche!");

return bt->left;

}

BTree rightChild(BTree bt){

if(isEmptyBTree(bt)) erreur("Pas de fils droit!");

return bt->right;

}

int isLeaf(BTree bt){

return !isEmptyBTree(bt) &&

isEmptyBTree(leftChild(bt)) &&

isEmptyBTree(rightChild(bt));

}

void freeNode(Node *c){

(40)

Arbres binaires modifiables

(41)

Quelques fonctions de modification

Fonctions “bas niveau” pour ins´erer ou supprimer des ´el´ements dans un arbre :

void insertRight(Node *n, Element e);

void insertLeft(Node *n, Element e);

Element deleteRight(Node *n);

Element deleteLeft(Node *n);

void insertRightmostNode(BTree *bt, Element e);

void insertLeftmostNode(BTree *bt, Element e);

Element deleteRightmostNode(BTree *bt);

Element deleteLeftmostNode(BTree *bt);

(42)

Quelques fonctions de modification

void insertRight(Node *n, Element e){

if(!isEmptyBTree(n) && isEmptyBTree(rightChild(n))) n->right=makeLeaf(e);

else erreur("insertRight impossible!");

}

void insertLeft(Node *n, Element e){

if(!isEmptyBTree(n) && isEmptyBTree(leftChild(n))) n->left=makeLeaf(e);

else erreur("insertLeft impossible!");

}

Element deleteRight(Node *n){

if(isEmptyBTree(n) || !isLeaf(rightChild(n))) erreur("deleteRight imossible!");

Element res=root(n->right);

(43)

Quelques fonctions de modification

Element deleteLeft(Node *n){

if(isEmptyBTree(n) || !isLeaf(leftChild(n))) erreur("deleteLeft imossible!");

Element res=root(n->left);

n->left=makeEmptyBTree();

return res;

}

void insertRightmostNode(BTree *bt, Element e){

if(isEmptyBTree(*bt))

*bt=makeLeaf(e);

else{

BTree tmp=*bt;

while(!isEmptyBTree(rightChild(tmp))) tmp=rightChild(tmp);

(44)

Quelques fonctions de modification

Element deleteLeftmostNode(BTree *bt){

Element res;

if(isEmptyBTree(*bt))

erreur("deleteLeftmostNode imossible!");

if(isEmptyBTree(leftChild(*bt))){

res=root(*bt);

*bt=rightChild(*bt);

} else{

BTree tmp=*bt;

while(!isEmptyBTree(leftChild(leftChild(tmp)))) tmp=leftChild(tmp);

res=root(leftChild(tmp));

tmp->left=(tmp->left)->right;

}

(45)

Extensions

(46)

Extensions

Probl`emes avec les arbres binaires (`a nnoeuds) : Chercher un ´el´ement coˆute cher : O(n) ;

Ins´erer un ´el´ement (pas n’importe o`u !) : O(n) ; Supprimerun ´el´ement : on ne peut pas toujours...

Solution ? Ordonner (trier) les ´el´ements dans l’arbre...

Un arbre binaire de recherche (BST) est : soitvide,

soit un noeud :

contenant une donn´ee (laracine), dont le fils gauche est unBSTdont les ´el´ements sont inf´erieurs `a la racine,

8 10 5

11

1 7

0 6

9 2

4

(47)

Extensions (suite)

Arbre binaire ´equilibr´e (AVL) : les hauteurs des deux sous- arbres d’un mˆeme noeud diff`erent au plus de 1.

8

10 5

11

1 7

0 6

3

9 2

4

BST (pas AVL)

7

9 4

10

1 6

0 5 11

8 2

3

AVL

(48)

Extensions - fin

Un arbre g´en´eral (chaque noeud a une listede fils :)

8

6 3

11

13 1

0 18

14

10 5

7

15 12

16 9

2

Références

Documents relatifs

[r]

Dans un premier temps, on r´ epondra aux questions ` a l’´ ecrit puis pour v´ erifier que nos algorithmes sont bien ´ ecrits, on les programmera sur machine.. Exercice

• Ecrire la m´ ethode r´ ecursive “public String reverse(String s)” qui renvoie la chaine s ´ ecrite en sens inverse.. En d´ eduire une version it´ erative de la m´

Eseuri in onoa rea lui J1ihai Sora (Dialogue et liberte. Le premi er a l'avoir fait a ete Toma Pavel, qui etait proche de Nicolae Steinhardt, de Augustin de Nicolae

On souhaite faire l’affichage d’un tableau

arbreCons : element × arbre × arbre → arbre construit un arbre binaire dont la racine est l’´ el´ ement, l’arbre gauche le deuxi` eme argument, l’arbre le troisi` eme racine

[r]

[r]