IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Algorithmes et structures de données Discussion :

Algorithme de suppression d'un élément dans un arbre binaire de recherche


Sujet :

Algorithmes et structures de données

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut Algorithme de suppression d'un élément dans un arbre binaire de recherche
    salut a tous !
    S.V.P, Je cherche l'algorithme de suppression d'un élément dans un arbre binaire de recherche !
    voila mes essais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    type abr=^elt;
    elt=enregistrement
    val:entier;
    g,d:abr;
    fin;
    ......
    ......
    ......
    fonction recherche(a:abr;v:entier):abr
    debut
    si (a=null)alors recherche<==null
    sinon si (a^.val=v)alors recherche<==a
    sinon si (a^.val>v) alors recherche <==recherche(a^.g,v)
    sinon recherche <==recherche (a^.d,v);
    fin;
    ......
    ......
    ......
    fonction succ(var a:abr):abr
    var p:abr;
    debut
    si (a<>null)alors
    debut
    si (a^.d<>null) alors
    debut
    p<==a^.d;
    tantque(p^.g^.g<>null)alors p<==p^.g;
    fin;
    succ<==p;
    fin;
    fin;
    ......
    ......
    ......
    procedure supp(a:abr;v)
    var x:abr; 
    debut
    x<==recherche(a,v);
    si (x=null)alors ecrire"la valeur que vous voulez supprimé nexiste pas dans cet arbe"
    sinon
    debut
    si((x^.g=null)et(x^.d=null)) alors dispose(x)
    sinon si ((x^.d<>null)et(x^.g=null))alors
    debut
    s<==succ(x);
    x^.val<==s^.val;
    dispose(s);
    fin
    sinon si((x^.d<>null)et(x^.g<>null))alors
    debut
    s<==succ(x);
    x^.val<==s^.val;
    dispose(s);
    fin
    sinon
    debut
    x^.val<==x^.g^.val;
    dispose(x^.g);
    fin;
    fin;
    j'ai trouvé l'idée sur wiki (mais honnêtement j'ai pas pu le faire):
    plusieurs cas sont à considérer, une fois que le nœud à supprimer a été trouvé à partir de sa clé :

    * Suppression d'une feuille : Il suffit de l'enlever de l'arbre vu qu'elle n'a pas de fils.
    * Suppression d'un nœud avec un enfant : Il faut l'enlever de l'arbre en le remplaçant par son fils.
    * Suppression d'un nœud avec deux enfants : Supposons que le nœud à supprimer soit appelé N (le nœud de valeur 7 dans le graphique ci-dessous). On le remplace alors par son successeur le plus proche (le nœud le plus à gauche du sous-arbre droit - ci-dessous, le nœud de valeur 9) ou son plus proche prédécesseur (le nœud le plus à droite du sous-arbre gauche - ci-dessous, le nœud de valeur 6). Cela permet de garder une structure d'arbre binaire de recherche. Puis on applique à nouveau la procédure de suppression à N, qui est maintenant une feuille ou un nœud avec un seul fils.

    Pour une implémentation efficace, il est déconseillé d'utiliser uniquement le successeur ou le prédécesseur car cela contribue à déséquilibrer l'arbre.

    Dans tous les cas cette opération requiert de parcourir l'arbre de la racine jusqu'à une feuille : le temps d'exécution est donc proportionnel à la profondeur de l'arbre qui vaut n dans le pire des cas, d'où une complexité maximale en O(n).

  2. #2
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    n'hésitez pas a me critiqué,guidé ou corrigé s'il y a des fautes svp

  3. #3
    Membre émérite
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Points : 2 464
    Points
    2 464
    Par défaut
    Exemple de code en Python et C++ : http://en.wikipedia.org/wiki/Binary_..._tree#Deletion

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par Franck Dernoncourt Voir le message
    j'ai aucune idée sur le langage python ! es que c'est possible de l'aidé avec des pseudo code ?

  5. #5
    Membre émérite
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Points : 2 464
    Points
    2 464

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par Franck Dernoncourt Voir le message
    non plus , je suis amateur

  7. #7
    Membre émérite
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Points : 2 464
    Points
    2 464

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    Je maitrise que le PASCAL, et en ce moment je suis entrain d'apprendre le C

  9. #9
    Membre émérite
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Points : 2 464
    Points
    2 464
    Par défaut
    Google "Binary search tree remove pascal".
    Tu trouveras cela notamment : (pas lu)

    http://pascalprog.blogspot.com/2008/...arch-tree.html :
    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    (**************************************************************)
    (******* BINARY SEARCH TREE ADT ********)
    (**************************************************************)
     
    TYPE
    KeyType = Integer; (* the type of key in Info part *)
     
    TreeElementType = RECORD (* the type of the user's data *)
    Key : KeyType;
    (* other fields as needed. *)
    END; (* TreeElementType *)
     
    TreePtrType = ^TreeNodeType;
     
    TreeNodeType = RECORD
    Info : TreeElementType; (* the user's data *)
    Left : TreePtrType; (* pointer to left child *)
    Right : TreePtrType (* pointer to right child *)
    END; (* TreeNodeType *)
     
    TreeType = TreePtrType;
     
    TraversalType = (Preorder, Inorder, Postorder);
     
    (******************************************************)
     
    PROCEDURE CreateTree
    (VAR Tree : TreeType);
     
    (* Initializes Tree to empty state. *)
     
    BEGIN (* CreateTree *)
    Tree := NIL
    END; (* CreateTree *)
     
    (*************************************************)
     
    PROCEDURE FindNode
    ( Tree : TreeType;
    KeyValue : KeyType;
    VAR NodePtr : TreePtrType;
    VAR ParentPtr : TreePtrType);
     
    (* Find the node that contains KeyValue; set NodePtr to *)
    (* point to the node and ParentPtr to point to its parent; *)
     
    VAR
    Found : Boolean; (* KeyValue found in tree? *)
     
    BEGIN (* FindNode *)
     
    (* Set up to search. *)
    NodePtr := Tree;
    ParentPtr := NIL;
    Found := False;
     
    (* Search until no more nodes to search or until found. *)
    WHILE (NodePtr <> NIL) AND NOT Found DO
    IF NodePtr^.Info.Key = KeyValue
    THEN Found := True
     
    ELSE (* Advance pointers. *)
    BEGIN
     
    ParentPtr := NodePtr;
     
    IF NodePtr^.Info.Key > KeyValue
    THEN NodePtr := NodePtr^.Left
    ELSE NodePtr := NodePtr^.Right
     
    END (* advance pointers *)
    END; (* FindNode *)
     
    (********************************************************)
     
    PROCEDURE RetrieveElement
    (Tree : TreeType;
    KeyValue : KeyType;
    VAR Element : TreeElementType;
    VAR ValueInTree : Boolean);
     
    (* Searches the binary search tree for the element whose *)
    (* key is KeyValue, and returns a copy of the element. *)
     
    VAR
    NodePtr : TreePtrType; (* pointer to node with KeyValue *)
    ParentPtr : TreePtrType; (* used for FindNode interface *)
     
    BEGIN (* RetrieveElement *)
     
    (* Find node in tree that contains KeyValue. *)
    FindNode (Tree, KeyValue, NodePtr, ParentPtr);
     
    ValueInTree := (NodePtr <> NIL);
     
    IF ValueInTree
    THEN Element := NodePtr^.Info
     
    END; (* RetrieveElement *)
     
    (***********************************************************)
     
    PROCEDURE ModifyElement
    (VAR Tree : TreeType;
    ModElement : TreeElementType);
     
    (* ModElement replaces existing tree element with same key. *)
    VAR
    NodePtr : TreePtrType; (* pointer to node with KeyValue *)
    ParentPtr : TreePtrType; (* used for FindNode interface *)
     
    BEGIN (* ModifyElement *)
     
    (* Find the node with the same key as ModElement.Key. *)
    FindNode (Tree, ModElement.Key, NodePtr, ParentPtr);
     
    (* NodePtr points to the tree node with same key. *)
    NodePtr^.Info := ModElement
     
    END; (* ModifyElement *)
     
    (***************************************************************)
     
    PROCEDURE InsertElement
    (VAR Tree : TreeType;
    Element : TreeElementType);
     
    (* Add Element to the binary search tree. Assumes that no *)
    (* element with the same key exists in the tree. *)
     
    VAR
    NewNode : TreePtrType; (* pointer to new node *)
    NodePtr : TreePtrType; (* used for FindNode call *)
    ParentPtr : TreePtrType; (* points to new node's parent *)
     
    BEGIN (* InsertElement *)
     
    (* Create a new node. *)
    New (NewNode);
    NewNode^.Left := NIL;
    NewNode^.Right := NIL;
    NewNode^.Info := Element;
     
    (* Search for the insertion place. *)
    FindNode (Tree, Element.Key, NodePtr, ParentPtr);
     
    (* IF this is first node in tree, set Tree to NewNode; *)
    (* otherwise, link new node to Node(ParentPtr). *)
    IF ParentPtr = NIL
    THEN Tree := NewNode (* first node in the tree *)
    ELSE (* Add to the existing tree. *)
    IF ParentPtr^.Info.Key > Element.Key
    THEN ParentPtr^.Left := NewNode
    ELSE ParentPtr^.Right := NewNode
     
    END; (* InsertElement *)
     
    (**********************************************************)
    { The following code has been commented out:
    PROCEDURE InsertElement
    (VAR Tree : TreeType;
    Element : TreeElementType);
     
    (* Recursive version of InsertElement operation. *)
     
    BEGIN (* InsertElement *)
     
    IF Tree = NIL
    THEN (* Base Case: allocate new leaf Node(Tree) *)
    BEGIN
    New (Tree);
    Tree^.Left := NIL;
    Tree^.Right := NIL;
    Tree^.Info := Element
    END (* IF Tree = NIL *)
     
    ELSE (* General Case: InsertElement into correct subtree *)
    IF Element.Key < Tree^.Info.Key
    THEN InsertElement (Tree^.Left, Element)
    ELSE InsertElement (Tree^.Right, Element)
     
    END; (* InsertElement *)
    }
     
    (**********************************************************)
     
    PROCEDURE DeleteElement
    (VAR Tree : TreeType;
    KeyValue : KeyType);
     
    (* Deletes the element containing KeyValue from the binary *)
    (* search tree pointed to by Tree. Assumes that this key *)
    (* value is known to exist in the tree. *)
     
    VAR
    NodePtr : TreePtrType; (* pointer to node to be deleted *)
    ParentPtr : TreePtrType; (* pointer to parent of delete node *)
     
    (********************* Nested Procedures ***********************)
     
    PROCEDURE FindAndRemoveMax
    (VAR Tree : TreePtrType;
    VAR MaxPtr : TreePtrType);
     
    BEGIN (* FindAndRemoveMax *)
     
    IF Tree^.Right = NIL
    THEN (* Base Case: maximum found *)
    BEGIN
    MaxPtr := Tree; (* return pointer to max node *)
    Tree := Tree^.Left (* unlink max node from tree *)
    END (* Base Case *)
     
    ELSE (* General Case: find and remove from right subtree *)
    FindAndRemoveMax (Tree^.Right, MaxPtr)
     
    END; (* FindAndRemoveMax *)
     
    (*************************************************************)
     
    PROCEDURE DeleteNode
    (VAR NodePtr : TreePtrType);
     
    (* Deletes the node pointed to by NodePtr from the binary *)
    (* search tree. NodePtr is a real pointer from the parent *)
    (* node in the tree, not an external pointer. *)
     
    VAR
    TempPtr : TreePtrType; (* node to delete *)
     
    BEGIN (* DeleteNode *)
     
    (* Save the original pointer for freeing the node. *)
    TempPtr := NodePtr;
     
    (* Case of no children or one child: *)
    IF NodePtr^.Right = NIL
    THEN NodePtr := NodePtr^.Left
     
    ELSE (* There is at least one child. *)
    IF NodePtr^.Left = NIL
    THEN (* There is one child. *)
    NodePtr := NodePtr^.Right
     
    ELSE (* There are two children. *)
    BEGIN
    (* Find and remove the replacement value from *)
    (* Node(NodePtr)'s left subtree. *)
    FindAndRemoveMax (NodePtr^.Left, TempPtr);
     
    (* Replace the delete element. *)
    NodePtr^.Info := TempPtr^.Info
     
    END; (* There are two children. *)
     
    (* Free the unneeded node. *)
    Dispose (TempPtr)
     
    END; (* DeleteNode *)
    (*****************************************************************)
     
    BEGIN (* DeleteElement *)
     
    (* Find node containing KeyValue. *)
    FindNode (Tree, KeyValue, NodePtr, ParentPtr);
     
    (* Delete node pointed to by NodePtr. ParentPtr points *)
    (* to the parent node, or is NIL if deleting root node. *)
    IF NodePtr = Tree
    THEN (* Delete the root node. *)
    DeleteNode (Tree)
    ELSE
    IF ParentPtr^.Left = NodePtr
    THEN (* Delete the left child node. *)
    DeleteNode (ParentPtr^.Left)
    ELSE (* Delete the right child node. *)
    DeleteNode (ParentPtr^.Right)
     
    END; (* DeleteElement *)
     
    (***********************************************************)
     
    {The following procedure has been commented out:
    PROCEDURE DeleteElement
    (VAR Tree : TreeType;
    KeyValue : KeyType);
     
    (* Recursive version of DeleteElement operation. *)
     
    BEGIN (* DeleteElement *)
     
    IF KeyValue = Tree^.Info.Key
    THEN (* Base Case : delete this node *)
    DeleteNode (Tree)
     
    ELSE
    IF KeyValue < Tree^.Info.Key
    THEN (* General Case 1: delete node from left subtree *)
    DeleteElement (Tree^.Left, KeyValue)
    ELSE (* General Case 2: delete node from right subtree *)
    DeleteElement (Tree^.Right, KeyValue)
     
    END; (* DeleteElement *)
    }
     
    (****************************************************************)
     
    PROCEDURE PrintTree
    (Tree : TreeType;
    TraversalOrder : TraversalType);
     
    (* Print all the elements in the tree, in the order *)
    (* specified by TraversalOrder. *)
     
    (********************** Nested Procedures ************************)
     
    PROCEDURE PrintNode
    (Element : TreeElementType);
     
    BEGIN (* PrintNode *)
     
    Writeln (Element.Key);
    (* other statements as needed *)
     
    END; (* PrintNode *)
     
    (*********************************************************)
     
    PROCEDURE PrintInorder
    (Tree : TreeType);
     
    (* Prints out the elements in a binary search tree in *)
    (* order from smallest to largest. This procedure is *)
    (* a recursive solution. *)
     
    BEGIN (* PrintInorder *)
     
    (* Base Case: If Tree is NIL, do nothing. *)
    IF Tree <>NIL
    THEN
     
    BEGIN (* General Case *)
     
    (* Traverse left subtree to print smaller values. *)
    PrintInorder(Tree^.Left);
     
    (* Print the information in this node. *)
    PrintNode(Tree^.Info);
    (* Traverse right subtree to print larger values. *)
    PrintInorder(Tree^.Right)
     
    END (* General Case *)
    END; (* PrintInorder *)
     
    (***************************************************************)
     
    PROCEDURE PrintPreorder
    (Tree : TreeType);
     
    (* Print out the elements in a binary search tree in *)
    (* preorder. This procedure is a recursive solution. *)
     
    BEGIN (* PrintPreorder *)
     
    (* Base Case: IF Tree is NIL, do nothing. *)
    IF Tree <> NIL
    THEN (* General Case *)
    BEGIN
     
    (* Print the value of this node. *)
    PrintNode(Tree^.Info);
     
    (* Traverse the left subtree in preorder. *)
    PrintPreorder(Tree^.Left);
     
    (* Traverse the left subtree in preorder. *)
    PrintPreorder(Tree^.Right)
     
    END (* General Case *)
    END; (* PrintPreorder *)
     
    (***********************************************************)
     
    PROCEDURE PrintPostorder
    (Tree : TreeType);
     
    (* Prints out the elements in a binary search tree in *)
    (* postorder. This procedure is a recursive solution. *)
     
    BEGIN (* PrintPostorder *)
     
    (* Base Case: If Tree is NIL, do nothing. *)
    IF Tree <> NIL
    THEN (* General Case *)
    BEGIN
     
    (* Traverse the left subtree in postorder. *)
    PrintPostorder(Tree^.Left);
     
    (* Traverse the right subtree in postorder. *)
    PrintPostorder(Tree^.Right);
     
    (* Print the value of this node. *)
    PrintNode(Tree^.Info)
     
    END (* General Case *)
    END; (* PrintPostorder *)
    (********************************************************)
     
    BEGIN (* PrintTree *)
     
    (* Call internal print procedure according to TraversalOrder. *)
    CASE TraversalOrder OF
    Preorder : PrintPreorder (Tree);
    Inorder : PrintInorder (Tree);
    Postorder : PrintPostorder (Tree)
    END (* CASE *)
     
    END; (* PrintTree *)
     
    (***********************************************************)
     
    PROCEDURE DestroyTree
    (VAR Tree : TreeType);
     
    (* Removes all the elements from the binary search tree *)
    (* rooted at Tree, leaving the tree empty. *)
     
    BEGIN (* DestroyTree *)
     
    (* Base Case: If Tree is NIL, do nothing. *)
    IF Tree <> NIL
    THEN (* General Case *)
    BEGIN
     
    (* Traverse the left subtree in postorder. *)
    DestroyTree (Tree^.Left);
     
    (* Traverse the right subtree in postorder. *)
    DestroyTree (Tree^.Right);
     
    (* Delete this leaf node from the tree. *)
    Dispose (Tree);
     
    END (* General Case *)
    END; (* DestroyTree *)
     
    (***********************************************************)

    et http://www.cs.grinnell.edu/~stone/co...rch-trees.html :
    A binary search tree is a recursively defined data structure that simplifies the process of conducting binary searches by marking appropriate bisection points structurally instead of requiring them to be computed. Unlike an array, it also allows for the efficient insertion of new items in the data structure during program execution.
    
    Here's the recursive definition: A binary search tree B either is empty or consists of a datum (typically a record that includes a key field) and two binary search trees L and R, called the left and right subtrees of B. Either or both of these subtrees may of course be empty. An invariant condition of every non-empty binary search tree B is that if its left subtree L is not empty, the key of the record stored at L is less than the key of the record stored at B (or precedes it in some conventional ordering of the key data type), and similarly that if B's right subtree R is not empty, the key of the datum stored at R is greater than the key of the record stored at B. This invariant must be preserved whenever the contents of a binary search tree are changed.
    
    In Pascal, one can use pointers to implement this data type, as follows:
    
    type
      Element = record
                  Key: KeyType;
                  { and presumably other fields }
                end;
      BinarySearchTree = ^Component;
      Component = record
                    Datum: Element;
                    Left, Right: BinarySearchTree
                  end;
    An empty binary search tree is represented by a nil pointer, a non-empty one by a pointer to a component containing the datum and two binary search trees.
    Creating an empty binary search tree, or one that contains just one datum, is trivial, as is testing whether a given binary search tree is empty:
    
    function MakeEmptyBinarySearchTree: BinarySearchTree;
    begin
      MakeEmptyBinarySearchTree := nil
    end;
    
    function MakeSingletonBinarySearchTree (Elm: Element): BinarySearchTree;
    var
      Result: BinarySearchTree;
    begin
      New (Result);
      Result^.Datum := Elm;
      Result^.Left := MakeEmptyBinarySearchTree;
      Result^.Right := MakeEmptyBinarySearchTree;
      MakeSingletonBinarySearchTree := Result
    end;
    
    function EmptyBinarySearchTree (B: BinarySearchTree): Boolean;
    begin
      EmptyBinarySearchTree := (B = nil)
    end;
    Suppose, however, that one wants to add a datum to an existing binary search tree B. This is again trivial if B is empty; one simply replaces B with the singleton binary search tree containing just the new datum. But if B is non-empty one must be careful to preserve the invariant stated above. Recursion provides a simple way to do this: Compare the datum to be inserted with the one stored at B. If the datum to be inserted is less than B, insert it into B's left subtree; otherwise, insert it into B's right subtree. In either case, perform the replacement by making a recursive call to the insertion procedure. The recursion will bottom out when one reaches a subtree of a subtree of a subtree, etc., that is empty. Replace this one with the singleton binary search tree containing just the new datum.
    Or in Pascal:
    
    procedure InsertIntoBinarySearchTree (Elm: Element; var B: BinarySearchTree);
    begin
      if EmptyBinarySearchTree (B) then
        B := MakeSingletonBinarySearchTree (Elm)
      else if Elm.Key < B^.Datum.Key then
        InsertIntoBinarySearchTree (Elm, B^.Left)
      else
        InsertIntoBinarySearchTree (Elm, B^.Right)
    end;
    Recursion is also the appropriate tool when one wants to search a binary search tree, perhaps to recover a record containing a specified key:
    function SearchBinarySearchTree (Sought: KeyType; B: BinarySearchTree;
       var Found: Element): Boolean;
    begin
      if EmptyBinarySearchTree (B) then
        SearchBinarySearchTree := False
      else if Sought < B^.Datum.Key then
        SearchBinarySearchTree := SearchBinarySearchTree (Sought, B^.Left, Found)
      else if B^.Datum.Key < Sought then
        SearchBinarySearchTree := SearchBinarySearchTree (Sought, B^.Right, Found)
      else begin
        SearchBinarySearchTree := True; { because Sought = B^.Datum.Key }
        Found := B^.Datum
      end
    end;
    In procedure InsertIntoBinarySearchTree and function SearchBinarySearchTree, only one branch of the tree is explored. Subtrees that contain elements that can't possibly be relevant to the insertion or to the search are bypassed. Occasionally, however, one wants to perform some operation on each of the data stored in a tree, specifically in ascending order. For instance, one might want to write out an index of the collection of records stored in the tree -- a list of the keys, in ascending order, one to a line. Recursion can be used for this purpose, too, but there will be two recursive calls rather than one, corresponding to the fact that each non-empty binary search tree contains two subtrees:
    procedure PrintBinarySearchTreeData (B: BinarySearchTree);
    begin
      if not EmptyBinarySearchTree (B) then begin
        PrintBinarySearchTreeData (B^.Left);
        writeln (B^.Datum.Key);
        PrintBinarySearchTreeData (B^.Right)
      end
    end;
    Notice that the keys for all of the data stored in B's left subtree will be printed out before the key for the datum actually stored at B (since, under the invariant, all those keys will precede the one stored at B in the desired ordering), while all those stored in the right subtree will be printed only after the key for the datum stored at B. This technique for traversing a binary tree is called an inorder traversal. One can generalize it by abstracting the procedure to be performed on each datum:
    procedure ApplyThroughoutBinarySearchTree (var B: BinarySearchTree;
        procedure P (var Elm: Element));
    begin
      if not EmptyBinarySearchTree (B) then begin
        ApplyThroughoutBinarySearchTree (B^.Left, P);
        P (B^.Datum);
        ApplyThroughoutBinarySearchTree (B^.Right, P)
      end
    end;
    It would alternatively be possible to perform some operation on the datum at each non-empty binary tree before proceeding to its left and right subtrees; a traversal that is arranged in this way is called a preorder traversal. Still another arrangement is to defer the processing of the datum at each non-empty binary tree until after the data in both of its subtrees have been dealt with; this is a postorder traversal. A postorder traversal is used, for instance, when deallocating a binary tree:
    procedure DeallocateBinarySearchTree (var B: BinarySearchTree);
    begin
      if not EmptyBinarySearchTree (B) then begin
        DeallocateBinarySearchTree (B^.Left);
        DeallocateBinarySearchTree (B^.Right);
        Dispose (B)
      end
    end;
    A postorder traversal is necessary in this case because after the storage at the other end of the pointer B has been recycled, there would be no way to reach B^.Left or B^.Right.
    Deleting a single datum from a binary search tree is in some cases a rather delicate operation. If the datum is stored at a position where both the left and right subtrees are empty, the binary search tree can be treated as a singleton and simply replaced with an empty BinarySearchTree. If one of the subtrees is empty and the other is not, the non-empty subtree can simply be promoted into the position occupied by its parent; this will not affect the truth of the invariant, since all of the elements in that subtree will still be in the same order relative to everything outside that subtree.
    
    The most difficult case arises, then, when the datum to be deleted is at a position where both of the subtrees are non-empty. The solution is to find one of the two data that is adjacent, in preorder, to the one to be deleted -- either the element in the left subtree that has the largest key, or the element in the right subtree that has the smallest key. (The choice between these alternatives is arbitrary, so in this implementation I've arranged for the selection of the former.) It is impossible for this adjacent element to be at a position where both of its subtrees are non-empty (otherwise one of its subtrees would contain an element still closer to the datum to be deleted). So this adjacent element can be copied up into the record containing the datum to be deleted, overwriting it, and then the adjacent element can itself be deleted by one of the relatively easy methods described in the previous paragraph.
    
    Here's how it looks in Pascal. In this version, the deletion procedure has no effect if the caller specifies a key that does not correspond to any of the elements of the binary search tree.
    
    procedure DeleteFromBinarySearchTree (Sought: KeyType;
      var B: BinarySearchTree);
    var
      Delend: BinarySearchTree;
        { a spare pointer to the component to be recycled }
    
      { The DeleteLargest function finds and returns the largest element in
        a given binary search tree and simultaneously deletes it from that
        binary search tree.  It presupposes that the binary search tree is not
        empty. }
    
      function DeleteLargest (var Site: BinarySearchTree): Element;
      var
        Delend: BinarySearchTree;
          { a spare pointer to the Component to be recycled }
      begin
        if EmptyBinarySearchTree (Site^.Right) then begin
          DeleteLargest := Site^.Datum;
          Delend := Site;
          Site := Site^.Left;
          Dispose (Delend)
        end
        else
          DeleteLargest := DeleteLargest (Site^.Right)
      end;
    
    begin { procedure DeleteFromBinarySearchTree }
      if B <> nil then begin
        if Sought < B^.Datum.Key then
          DeleteFromBinarySearchTree (Sought, B^.Left)
        else if B^.Datum.Key < Sought then
          DeleteFromBinarySearchTree (Sought, B^.Right)
        else begin { we've found the datum to be deleted }
          if EmptyBinarySearchTree (B^.Left) then begin
            Delend := B;
            B := B^.Right;
            Dispose (Delend)
          end
          else if EmptyBinarySearchTree (B^.Right) then begin
            Delend := B;
            B := B^.Left;
            Dispose (Delend)
          end
          else
            B^.Datum := DeleteLargest (B^.Left)
        end
      end
    end;
    Given an array of records of type Element, here's a procedure that will sort them by inserting them into a binary search tree and then copying them back out again:
    type
      ElementArray = array [1 .. ArraySize] of Element;
    
    procedure BinarySearchTreeSort (var Arr: ElementArray);
    var
      Container: BinarySearchTree;
      Index: integer;
    
      procedure Restore (var Elm: Element);
      begin
        Index := Index + 1;
        Arr[Index] := Elm
      end;
    
    begin
      Container := MakeEmptyBinarySearchTree;
      for Index := 1 to ArraySize do
        InsertIntoBinarySearchTree (Arr[Index], Container);
      Index := 0;
      ApplyThroughoutBinarySearchTree (Container, Restore);
      DeallocateBinarySearchTree (Container)
    end;
    Alternatively, one might read the elements in from a file of records of type Element and write them back out to the same file in sorted order:
    type
      ElementFile = file of Element;
    
    procedure BinarySearchTreeSortFile (var F: ElementFile);
    var
      Container: BinarySearchTree;
    
      procedure WriteToFile (var Elm: Element);
      begin
        Write (F, Elm)
      end;
    
    begin
      Reset (F);
      Container := MakeEmptyBinarySearchTree;
      while not EOF (F) do begin
        InsertIntoBinarySearchTree (F^, Container);
        Get (F)
      end;
      Rewrite (F);
      ApplyThroughoutBinarySearchTree (Container, WriteToFile);
      DeallocateBinarySearchTree (Container)
    end;

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    un grand merci a vous !
    SVP, donnez moi votre avis sur le pseudo code que j'ai mis dans la première réponse dans ce sujet

  11. #11
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    338
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Algérie

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 338
    Points : 0
    Points
    0
    Par défaut
    a l'aide svp ..c'est urgent !

  12. #12
    Membre émérite
    Avatar de Franck Dernoncourt
    Homme Profil pro
    PhD student in AI @ MIT
    Inscrit en
    Avril 2010
    Messages
    894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : PhD student in AI @ MIT
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2010
    Messages : 894
    Points : 2 464
    Points
    2 464
    Par défaut
    Désolé, pas le temps de faire de relecture de code de mon côté en ce moment.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Suppression dans un arbre binaire de recherche
    Par allomona dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 06/12/2014, 08h51
  2. modifier une valeur dans un arbre binaire de recherche?
    Par paco_the_king dans le forum Langage
    Réponses: 2
    Dernier message: 04/02/2012, 20h26
  3. Réponses: 2
    Dernier message: 07/12/2009, 11h43
  4. Ajout dans les arbres binaires de recherche
    Par chouki dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 28/12/2008, 15h32
  5. Suppression dans un arbre binaire de recherche
    Par zeine77 dans le forum Langage
    Réponses: 1
    Dernier message: 11/05/2007, 20h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo