Nitno binarno stablo | Umetanje

Nitno binarno stablo | Umetanje

Već smo razgovarali o Binarno navojno binarno stablo .
Umetanje u binarno stablo s nitima slično je umetanju u binarno stablo, ali ćemo morati prilagoditi niti nakon umetanja svakog elementa.

C prikaz binarnog navojnog čvora: 

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; }; 

U sljedećem objašnjenju razmotrili smo Stablo binarnog pretraživanja (BST) za umetanje jer je umetanje definirano nekim pravilima u BST-ovima.
Neka tmp biti novo umetnuti čvor . Tijekom umetanja mogu postojati tri slučaja:

Slučaj 1: Umetanje u prazno stablo  

I lijevi i desni pokazivač tmp-a bit će postavljen na NULL i novi čvor postaje korijen. 

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

Slučaj 2: Kada je novi čvor umetnut kao lijevo dijete  

Nakon što smo čvor umetnuli na njegovo pravo mjesto, njegove lijeve i desne niti trebamo usmjeriti prema redoslijedu prethodnika odnosno nasljednika. Čvor koji je bio po redu nasljednik . Dakle, lijeva i desna nit novog čvora će biti- 

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

Prije umetanja lijevi pokazivač roditelja bio je nit, ali nakon umetanja to će biti veza koja pokazuje na novi čvor. 

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

Sljedeći primjer prikazuje čvor koji se umeće kao lijevo dijete svog roditelja. 
 

Nitno binarno stablo | Umetanje


Nakon umetanja 13 
 

Nitno binarno stablo | Umetanje


Prethodnik od 14 postaje prethodnik od 13 tako da lijeva nit od 13 pokazuje na 10. 
Nasljednik od 13 je 14, tako da desna nit od 13 pokazuje na lijevo dijete koje je 13. 
Lijevi pokazivač od 14 nije nit, sada pokazuje na lijevo dijete koje ima 13.

Slučaj 3: Kada je novi čvor umetnut kao pravo dijete  

Roditelj od tmp je njegov inorder prethodnik. Čvor koji je bio po redu nasljednik roditelja sada je po redu nasljednik ovog čvora tmp. Dakle, lijeva i desna nit novog čvora će biti- 

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

Prije umetanja desni pokazivač roditelja bio je nit, ali nakon umetanja to će biti poveznica koja pokazuje na novi čvor. 

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

Sljedeći primjer prikazuje čvor koji se umeće kao desno dijete svog roditelja. 
 

Nitno binarno stablo | Umetanje


Nakon 15 umetnutih 
 

Nitno binarno stablo | Umetanje


Nasljednik od 14 postaje nasljednik od 15 tako da desna nit od 15 pokazuje do 16 
Prethodnik od 15 je 14 tako da lijeva nit od 15 pokazuje na 14. 
Desni pokazivač od 14 nije nit, sada pokazuje na desno dijete koje ima 15.

C++ implementacija za umetanje novog čvora u Threaded Binary Search Tree:  
Kao standardni BST umetak tražimo ključnu vrijednost u stablu. Ako je ključ već prisutan, vraćamo se, inače se novi ključ umeće na mjestu gdje pretraga završava. U BST-u pretraživanje završava kada pronađemo ključ ili kada dođemo do NULL lijevog ili desnog pokazivača. Ovdje su svi lijevi i desni NULL pokazivači zamijenjeni nitima osim lijevog pokazivača prvog čvora i desnog pokazivača zadnjeg čvora. Dakle, ovdje će pretraga biti neuspješna kada dođemo do NULL pokazivača ili niti.

Implementacija:

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>   

Izlaz
5 10 13 14 16 17 20 30  

Vremenska složenost: O(log N)

Prostorna složenost: O(1) budući da se ne koristi dodatni prostor.

 

Napravi kviz