Menetes bináris fa | Beillesztés

Menetes bináris fa | Beillesztés

Már megbeszéltük a Bináris szálú bináris fa .
A bináris menetes fába történő beillesztés hasonló a bináris fába történő beszúráshoz, de minden elem beillesztése után módosítanunk kell a szálakat.

A bináris szálas csomópont C ábrázolása: 

struct Node { struct Node *left *right; int info; // false if left pointer points to predecessor // in Inorder Traversal boolean lthread; // false if right pointer points to successor // in Inorder Traversal boolean rthread; }; 

A következő magyarázatban figyelembe vettük Bináris keresőfa (BST) a beszúráshoz, mivel a beillesztést bizonyos szabályok határozzák meg a BST-ben.
Hadd tmp legyen az újonnan beillesztett csomópont . A beillesztés során három eset lehet:



1. eset: Beszúrás üres fába  

A tmp bal és jobb oldali mutatói NULL-ra lesznek állítva, és az új csomópont lesz a gyökér. 

root = tmp; tmp -> left = NULL; tmp -> right = NULL; 

2. eset: Amikor új csomópont került be a bal oldali gyermekként  

A csomópont megfelelő helyére történő beillesztése után a bal és jobb szálakat a sorrend elődjére, illetve utódjára kell mutatnunk. A csomópont, ami volt rend utódja . Tehát az új csomópont bal és jobb szála lesz- 

tmp -> left = par ->left; tmp -> right = par; 

A beszúrás előtt a szülő bal mutatója egy szál volt, de beillesztés után az új csomópontra mutató hivatkozás lesz. 

par -> lthread = false; par -> left = temp; 

A következő példa egy csomópontot a szülő bal oldali gyermekeként szúr be. 
 

Menetes bináris fa | Beillesztés


A 13 beillesztése után 
 

Menetes bináris fa | Beillesztés


A 14 elődje a 13 elődjévé válik, így a bal szál 13 pontról 10-re. 
A 13 utódja a 14, tehát a 13 pontos jobb oldali szál a bal gyermekhez képest, ami 13. 
A 14-es bal mutató nem egy szál, hanem a bal oldali gyermekre mutat, amely 13.

3. eset: Amikor az új csomópont a megfelelő gyermekként kerül beillesztésre  

A tmp szülője a rendes elődje. Az a csomópont, amely a szülő sorrendi utódja volt, most ennek a tmp csomópontnak a rendes utódja. Tehát az új csomópont bal és jobb szála lesz- 

tmp -> left = par; tmp -> right = par -> right; 

A beillesztés előtt a szülő jobb oldali mutatója egy szál volt, de beillesztés után az új csomópontra mutató hivatkozás lesz. 

par -> rthread = false; par -> right = tmp; 

A következő példa azt mutatja be, hogy egy csomópont a szülőjének megfelelő gyermekeként kerül beillesztésre. 
 

Menetes bináris fa | Beillesztés


15 beillesztés után 
 

Menetes bináris fa | Beillesztés


A 14 utódja a 15 utódja lesz, tehát a 15 pont jobb szála 16-hoz 
A 15 elődje a 14, tehát a bal szál 15 pontból 14-re. 
A 14-es jobb oldali mutató nem egy szál, hanem a 15-ös jobb gyermekre mutat.

C++ implementáció új csomópont beszúrásához a Threaded Binary Search Tree-ba:  
Mint szabványos BST betét a kulcsértéket keressük a fában. Ha a kulcs már jelen van, akkor visszatérünk, ellenkező esetben az új kulcsot beszúrjuk arra a pontra, ahol a keresés véget ér. A BST-ben a keresés akkor fejeződik be, amikor megtaláljuk a kulcsot, vagy amikor elérjük a NULL bal vagy jobb mutatót. Itt minden bal és jobb NULL mutatót szálak váltanak fel, kivéve az első csomópont bal mutatóját és az utolsó csomópont jobb oldali mutatóját. Tehát itt a keresés sikertelen lesz, ha elérünk egy NULL mutatót vagy egy szálat.

Végrehajtás:

C++
   // Insertion in Threaded Binary Search Tree.   #include       using     namespace     std  ;   struct     Node   {      struct     Node     *  left       *  right  ;      int     info  ;      // False if left pointer points to predecessor      // in Inorder Traversal      bool     lthread  ;      // False if right pointer points to successor      // in Inorder Traversal      bool     rthread  ;   };   // Insert a Node in Binary Threaded Tree   struct     Node     *  insert  (  struct     Node     *  root       int     ikey  )   {      // Searching for a Node with given value      Node     *  ptr     =     root  ;      Node     *  par     =     NULL  ;     // Parent of key to be inserted      while     (  ptr     !=     NULL  )      {      // If key already exists return      if     (  ikey     ==     (  ptr  ->  info  ))      {      printf  (  'Duplicate Key !  n  '  );      return     root  ;      }      par     =     ptr  ;     // Update parent pointer      // Moving on left subtree.      if     (  ikey      <     ptr  ->  info  )      {      if     (  ptr     ->     lthread     ==     false  )      ptr     =     ptr     ->     left  ;      else      break  ;      }      // Moving on right subtree.      else      {      if     (  ptr  ->  rthread     ==     false  )      ptr     =     ptr     ->     right  ;      else      break  ;      }      }      // Create a new node      Node     *  tmp     =     new     Node  ;      tmp     ->     info     =     ikey  ;      tmp     ->     lthread     =     true  ;      tmp     ->     rthread     =     true  ;      if     (  par     ==     NULL  )      {      root     =     tmp  ;      tmp     ->     left     =     NULL  ;      tmp     ->     right     =     NULL  ;      }      else     if     (  ikey      <     (  par     ->     info  ))      {      tmp     ->     left     =     par     ->     left  ;      tmp     ->     right     =     par  ;      par     ->     lthread     =     false  ;      par     ->     left     =     tmp  ;      }      else      {      tmp     ->     left     =     par  ;      tmp     ->     right     =     par     ->     right  ;      par     ->     rthread     =     false  ;      par     ->     right     =     tmp  ;      }      return     root  ;   }   // Returns inorder successor using rthread   struct     Node     *  inorderSuccessor  (  struct     Node     *  ptr  )   {      // If rthread is set we can quickly find      if     (  ptr     ->     rthread     ==     true  )      return     ptr  ->  right  ;      // Else return leftmost child of right subtree      ptr     =     ptr     ->     right  ;      while     (  ptr     ->     lthread     ==     false  )      ptr     =     ptr     ->     left  ;      return     ptr  ;   }   // Printing the threaded tree   void     inorder  (  struct     Node     *  root  )   {      if     (  root     ==     NULL  )      printf  (  'Tree is empty'  );      // Reach leftmost node      struct     Node     *  ptr     =     root  ;      while     (  ptr     ->     lthread     ==     false  )      ptr     =     ptr     ->     left  ;      // One by one print successors      while     (  ptr     !=     NULL  )      {      printf  (  '%d '    ptr     ->     info  );      ptr     =     inorderSuccessor  (  ptr  );      }   }   // Driver Program   int     main  ()   {      struct     Node     *  root     =     NULL  ;      root     =     insert  (  root       20  );      root     =     insert  (  root       10  );      root     =     insert  (  root       30  );      root     =     insert  (  root       5  );      root     =     insert  (  root       16  );      root     =     insert  (  root       14  );      root     =     insert  (  root       17  );      root     =     insert  (  root       13  );      inorder  (  root  );      return     0  ;   }   
Java
   // Java program Insertion in Threaded Binary Search Tree.    import     java.util.*  ;   public     class   solution   {   static     class   Node      {         Node     left       right  ;         int     info  ;             // False if left pointer points to predecessor       // in Inorder Traversal       boolean     lthread  ;             // False if right pointer points to successor       // in Inorder Traversal       boolean     rthread  ;      };          // Insert a Node in Binary Threaded Tree    static     Node     insert  (     Node     root       int     ikey  )      {         // Searching for a Node with given value       Node     ptr     =     root  ;         Node     par     =     null  ;     // Parent of key to be inserted       while     (  ptr     !=     null  )         {         // If key already exists return       if     (  ikey     ==     (  ptr  .  info  ))         {         System  .  out  .  printf  (  'Duplicate Key !n'  );         return     root  ;         }             par     =     ptr  ;     // Update parent pointer           // Moving on left subtree.       if     (  ikey      <     ptr  .  info  )         {         if     (  ptr     .     lthread     ==     false  )         ptr     =     ptr     .     left  ;         else      break  ;         }             // Moving on right subtree.       else      {         if     (  ptr  .  rthread     ==     false  )         ptr     =     ptr     .     right  ;         else      break  ;         }         }             // Create a new node       Node     tmp     =     new     Node  ();         tmp     .     info     =     ikey  ;         tmp     .     lthread     =     true  ;         tmp     .     rthread     =     true  ;             if     (  par     ==     null  )         {         root     =     tmp  ;         tmp     .     left     =     null  ;         tmp     .     right     =     null  ;         }         else     if     (  ikey      <     (  par     .     info  ))         {         tmp     .     left     =     par     .     left  ;         tmp     .     right     =     par  ;         par     .     lthread     =     false  ;         par     .     left     =     tmp  ;         }         else      {         tmp     .     left     =     par  ;         tmp     .     right     =     par     .     right  ;         par     .     rthread     =     false  ;         par     .     right     =     tmp  ;         }             return     root  ;      }          // Returns inorder successor using rthread    static     Node     inorderSuccessor  (     Node     ptr  )      {         // If rthread is set we can quickly find       if     (  ptr     .     rthread     ==     true  )         return     ptr  .  right  ;             // Else return leftmost child of right subtree       ptr     =     ptr     .     right  ;         while     (  ptr     .     lthread     ==     false  )         ptr     =     ptr     .     left  ;         return     ptr  ;      }          // Printing the threaded tree    static     void     inorder  (     Node     root  )      {         if     (  root     ==     null  )         System  .  out  .  printf  (  'Tree is empty'  );             // Reach leftmost node       Node     ptr     =     root  ;         while     (  ptr     .     lthread     ==     false  )         ptr     =     ptr     .     left  ;             // One by one print successors       while     (  ptr     !=     null  )         {         System  .  out  .  printf  (  '%d '    ptr     .     info  );         ptr     =     inorderSuccessor  (  ptr  );         }      }          // Driver Program    public     static     void     main  (  String  []     args  )   {         Node     root     =     null  ;             root     =     insert  (  root       20  );         root     =     insert  (  root       10  );         root     =     insert  (  root       30  );         root     =     insert  (  root       5  );         root     =     insert  (  root       16  );         root     =     insert  (  root       14  );         root     =     insert  (  root       17  );         root     =     insert  (  root       13  );             inorder  (  root  );      }      }   //contributed by Arnab Kundu   // This code is updated By Susobhan Akhuli   
Python3
   # Insertion in Threaded Binary Search Tree.    class   newNode  :   def   __init__  (  self     key  ):   # False if left pointer points to    # predecessor in Inorder Traversal    self  .  info   =   key   self  .  left   =   None   self  .  right   =  None   self  .  lthread   =   True   # False if right pointer points to    # successor in Inorder Traversal    self  .  rthread   =   True   # Insert a Node in Binary Threaded Tree    def   insert  (  root     ikey  ):   # Searching for a Node with given value    ptr   =   root   par   =   None   # Parent of key to be inserted    while   ptr   !=   None  :   # If key already exists return    if   ikey   ==   (  ptr  .  info  ):   print  (  'Duplicate Key !'  )   return   root   par   =   ptr   # Update parent pointer    # Moving on left subtree.    if   ikey    <   ptr  .  info  :   if   ptr  .  lthread   ==   False  :   ptr   =   ptr  .  left   else  :   break   # Moving on right subtree.    else  :   if   ptr  .  rthread   ==   False  :   ptr   =   ptr  .  right   else  :   break   # Create a new node    tmp   =   newNode  (  ikey  )   if   par   ==   None  :   root   =   tmp   tmp  .  left   =   None   tmp  .  right   =   None   elif   ikey    <   (  par  .  info  ):   tmp  .  left   =   par  .  left   tmp  .  right   =   par   par  .  lthread   =   False   par  .  left   =   tmp   else  :   tmp  .  left   =   par   tmp  .  right   =   par  .  right   par  .  rthread   =   False   par  .  right   =   tmp   return   root   # Returns inorder successor using rthread    def   inorderSuccessor  (  ptr  ):   # If rthread is set we can quickly find    if   ptr  .  rthread   ==   True  :   return   ptr  .  right   # Else return leftmost child of    # right subtree    ptr   =   ptr  .  right   while   ptr  .  lthread   ==   False  :   ptr   =   ptr  .  left   return   ptr   # Printing the threaded tree    def   inorder  (  root  ):   if   root   ==   None  :   print  (  'Tree is empty'  )   # Reach leftmost node    ptr   =   root   while   ptr  .  lthread   ==   False  :   ptr   =   ptr  .  left   # One by one print successors    while   ptr   !=   None  :   print  (  ptr  .  info    end  =  ' '  )   ptr   =   inorderSuccessor  (  ptr  )   # Driver Code   if   __name__   ==   '__main__'  :   root   =   None   root   =   insert  (  root     20  )   root   =   insert  (  root     10  )   root   =   insert  (  root     30  )   root   =   insert  (  root     5  )   root   =   insert  (  root     16  )   root   =   insert  (  root     14  )   root   =   insert  (  root     17  )   root   =   insert  (  root     13  )   inorder  (  root  )   # This code is contributed by PranchalK   
C#
   using     System  ;   // C# program Insertion in Threaded Binary Search Tree.    public     class     solution   {   public     class     Node   {      public     Node     left       right  ;      public     int     info  ;      // False if left pointer points to predecessor       // in Inorder Traversal       public     bool     lthread  ;      // False if right pointer points to successor       // in Inorder Traversal       public     bool     rthread  ;   }   // Insert a Node in Binary Threaded Tree    public     static     Node     insert  (  Node     root       int     ikey  )   {      // Searching for a Node with given value       Node     ptr     =     root  ;      Node     par     =     null  ;     // Parent of key to be inserted      while     (  ptr     !=     null  )      {      // If key already exists return       if     (  ikey     ==     (  ptr  .  info  ))      {      Console  .  Write  (  'Duplicate Key !n'  );      return     root  ;      }      par     =     ptr  ;     // Update parent pointer      // Moving on left subtree.       if     (  ikey      <     ptr  .  info  )      {      if     (  ptr  .  lthread     ==     false  )      {      ptr     =     ptr  .  left  ;      }      else      {      break  ;      }      }      // Moving on right subtree.       else      {      if     (  ptr  .  rthread     ==     false  )      {      ptr     =     ptr  .  right  ;      }      else      {      break  ;      }      }      }      // Create a new node       Node     tmp     =     new     Node  ();      tmp  .  info     =     ikey  ;      tmp  .  lthread     =     true  ;      tmp  .  rthread     =     true  ;      if     (  par     ==     null  )      {      root     =     tmp  ;      tmp  .  left     =     null  ;      tmp  .  right     =     null  ;      }      else     if     (  ikey      <     (  par  .  info  ))      {      tmp  .  left     =     par  .  left  ;      tmp  .  right     =     par  ;      par  .  lthread     =     false  ;      par  .  left     =     tmp  ;      }      else      {      tmp  .  left     =     par  ;      tmp  .  right     =     par  .  right  ;      par  .  rthread     =     false  ;      par  .  right     =     tmp  ;      }      return     root  ;   }   // Returns inorder successor using rthread    public     static     Node     inorderSuccessor  (  Node     ptr  )   {      // If rthread is set we can quickly find       if     (  ptr  .  rthread     ==     true  )      {      return     ptr  .  right  ;      }      // Else return leftmost child of right subtree       ptr     =     ptr  .  right  ;      while     (  ptr  .  lthread     ==     false  )      {      ptr     =     ptr  .  left  ;      }      return     ptr  ;   }   // Printing the threaded tree    public     static     void     inorder  (  Node     root  )   {      if     (  root     ==     null  )      {      Console  .  Write  (  'Tree is empty'  );      }      // Reach leftmost node       Node     ptr     =     root  ;      while     (  ptr  .  lthread     ==     false  )      {      ptr     =     ptr  .  left  ;      }      // One by one print successors       while     (  ptr     !=     null  )      {      Console  .  Write  (  '{0:D} '    ptr  .  info  );      ptr     =     inorderSuccessor  (  ptr  );      }   }   // Driver Program    public     static     void     Main  (  string  []     args  )   {      Node     root     =     null  ;      root     =     insert  (  root       20  );      root     =     insert  (  root       10  );      root     =     insert  (  root       30  );      root     =     insert  (  root       5  );      root     =     insert  (  root       16  );      root     =     insert  (  root       14  );      root     =     insert  (  root       17  );      root     =     insert  (  root       13  );      inorder  (  root  );   }   }      // This code is contributed by Shrikant13   
JavaScript
    <  script  >   // javascript program Insertion in Threaded Binary Search Tree.       class     Node     {      constructor  (){   this  .  left     =     null       this  .  right     =     null  ;      this  .  info     =     0  ;      // False if left pointer points to predecessor      // in Inorder Traversal      this  .  lthread     =     false  ;      // False if right pointer points to successor      // in Inorder Traversal      this  .  rthread     =     false  ;      }      }      // Insert a Node in Binary Threaded Tree      function     insert  (  root          ikey  )     {      // Searching for a Node with given value   var     ptr     =     root  ;   var     par     =     null  ;     // Parent of key to be inserted      while     (  ptr     !=     null  )     {      // If key already exists return      if     (  ikey     ==     (  ptr  .  info  ))     {      document  .  write  (  'Duplicate Key !n'  );      return     root  ;      }      par     =     ptr  ;     // Update parent pointer      // Moving on left subtree.      if     (  ikey      <     ptr  .  info  )     {      if     (  ptr  .  lthread     ==     false  )      ptr     =     ptr  .  left  ;      else      break  ;      }      // Moving on right subtree.      else     {      if     (  ptr  .  rthread     ==     false  )      ptr     =     ptr  .  right  ;      else      break  ;      }      }      // Create a new node   var     tmp     =     new     Node  ();      tmp  .  info     =     ikey  ;      tmp  .  lthread     =     true  ;      tmp  .  rthread     =     true  ;      if     (  par     ==     null  )     {      root     =     tmp  ;      tmp  .  left     =     null  ;      tmp  .  right     =     null  ;      }     else     if     (  ikey      <     (  par  .  info  ))     {      tmp  .  left     =     par  .  left  ;      tmp  .  right     =     par  ;      par  .  lthread     =     false  ;      par  .  left     =     tmp  ;      }     else     {      tmp  .  left     =     par  ;      tmp  .  right     =     par  .  right  ;      par  .  rthread     =     false  ;      par  .  right     =     tmp  ;      }      return     root  ;      }      // Returns inorder successor using rthread      function     inorderSuccessor  (  ptr  )     {      // If rthread is set we can quickly find      if     (  ptr  .  rthread     ==     true  )      return     ptr  .  right  ;      // Else return leftmost child of right subtree      ptr     =     ptr  .  right  ;      while     (  ptr  .  lthread     ==     false  )      ptr     =     ptr  .  left  ;      return     ptr  ;      }      // Printing the threaded tree      function     inorder  (  root  )     {      if     (  root     ==     null  )      document  .  write  (  'Tree is empty'  );      // Reach leftmost node   var     ptr     =     root  ;      while     (  ptr  .  lthread     ==     false  )      ptr     =     ptr  .  left  ;      // One by one print successors      while     (  ptr     !=     null  )     {      document  .  write  (  ptr  .  info  +  ' '  );      ptr     =     inorderSuccessor  (  ptr  );      }      }      // Driver Program       var     root     =     null  ;      root     =     insert  (  root       20  );      root     =     insert  (  root       10  );      root     =     insert  (  root       30  );      root     =     insert  (  root       5  );      root     =     insert  (  root       16  );      root     =     insert  (  root       14  );      root     =     insert  (  root       17  );      root     =     insert  (  root       13  );      inorder  (  root  );   // This code contributed by aashish1995    <  /script>   

Kimenet
5 10 13 14 16 17 20 30  

Időbonyolultság: O(log N)

A tér összetettsége: O(1) mivel nem használnak több helyet.

 

Kvíz létrehozása

Top Cikkek

Kategória

Érdekes Cikkek