Binarno stablo u strukturi podataka (PRIMJER)

Što je binarno stablo?

Riječ binarno znači dvoje. U strukturi podataka stabla "Binarno stablo" znači stablo u kojem svaki čvor može imati najviše dva podređena čvora (lijevi i desni čvor). To je jednostavno binarno stablo.

Međutim, postoji još jedno binarno stablo koje se najčešće koristi i ima nekoliko slučajeva upotrebe. Zove se binarno stablo pretraživanja (BST). Ovo stablo može učiniti algoritam pretraživanja puno bržim, točno log(n) vremensku složenost. U strukturi podataka n označava broj čvorova u binarnom stablu.

Koje su razlike između binarnog stabla i binarnog stabla pretraživanja?

Razlika između BST i običnog binarnog stabla je u tome što BST lijevi čvor ima manju vrijednost od korijenskog čvora, a desni čvor ima veću vrijednost od korijenskog čvora. Dakle, lijevo podstablo će uvijek sadržavati manju vrijednost od korijena, a desno podstablo će uvijek sadržavati veću vrijednost od korijena.

Razlike između binarnog stabla i binarnog stabla pretraživanja

Primjer stabala binarnog pretraživanja

Uzmimo sljedeći primjer za demonstraciju koncepata stabla binarnog pretraživanja.

Primjer stabala binarnog pretraživanja

Ovdje možete svi čvorovi slijediti zadanu disciplinu. Postoji formula za najveći broj čvorova u stablu binarnog pretraživanja. Ako promatramo gornje stablo, možemo vidjeti da svaki čvor ima dva djeteta osim svih lisnih čvorova. A visina(h) zadanog binarnog stabla je 4. Formula je 2h - 1. Dakle, daje 15.

Primjer stabala binarnog pretraživanja

Primjer stabala binarnog pretraživanja

Gornja slika nije potpuno binarno stablo ili uravnoteženo binarno stablo, zove se potpuno binarno stablo ili uravnoteženo binarno stablo. Postoji još jedna struktura podataka koja se zove AVL (još jedna vrsta binarnog stabla) koja optimizira visinu binarnog stabla i brže izvodi pretragu za BST kao na slici 3.

Pokušajte izračunati obilazak gore navedenog binarnog stabla po redu. Vidjet ćete da će dati sortirano polje koje se ne smanjuje, a algoritmi obilaska bit će isti kao i binarno stablo.

Vrste binarnog stabla

Evo nekoliko važnih vrsta binarnog stabla:

  • Potpuno binarno stablo: Svaki čvor može imati 0 ili 2 podređena čvora u ovom binarnom stablu. Samo jedan podređeni čvor nije dopušten u ovoj vrsti binarnog stabla. Dakle, osim čvora lista, svi čvorovi će imati 2 djece.

Vrste binarnog stabla

  • Potpuno binarno stablo: Svaki čvor može imati 0 ili 2 čvora. Čini se kao potpuno binarno stablo, ali svi elementi listova naslonjeni su na lijevo podstablo, dok u punom binarnom stablu čvor može biti u desnom ili lijevom podstablu.

Vrste binarnog stabla

  • Savršeno binarno stablo: Svi čvorovi moraju imati 0 ili 2 čvora, a svi čvorovi listova trebaju biti na istoj razini ili visini. Gornji primjer pune strukture binarnog stabla nije savršeno binarno stablo jer čvor 6 i čvor 1,2,3 nisu na istoj visini. Ali primjer potpunog binarnog stabla je savršeno binarno stablo.
  • Degenerirano binarno stablo: Svaki čvor može imati samo jedno dijete. Sve operacije poput pretraživanja, umetanja i brisanja oduzimaju O(N) vremena.

Vrste binarnog stabla

  • Uravnoteženo binarno stablo: Ovdje u ovom binarnom stablu razlika u visini lijevog i desnog podstabla je najviše 1. Dakle, dok dodajemo ili brišemo čvor, trebamo ponovno uravnotežiti visinu stabla. Ova vrsta samouravnoteženog binarnog stabla naziva se AVL stablo.

Vrste binarnog stabla

Tri su osnovne operacije BST-a. O njima se detaljno govori u nastavku.

Implementacija binarnog stabla u C i C++

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct Node
{
   int value;
   struct Node *left, *right;
}
struct Node *getEmptynode(int val)
{
   struct Node *tempNode = (struct Node *)malloc(sizeof(struct Node));
   tempNode->value = val;
   tempNode->left = NULL;
   tempNode->right = NULL;
   return tempNode;
}
struct Node *successor(struct Node *node)
{
    struct Node *present = node;
// going to the left most node
    while (present != NULL && present->left != NULL)
    {
       present = present->left;
    }
     return present;
 }
struct Node *insert(struct Node *node, int value)
{
   if (node == NULL)
   {
      return getEmptynode(value);
   }
   if (value < node->value)
   {
      node->left = insert(node->left, value);
   }
   else
   {
      node->right = insert(node->right, value);
   }
      return node;
}
int searchInBST(struct Node *node, int value)
{
   struct Node *current = node;
   while (current->value != value)
    {
    if (current->value > value)
      {
      current = current->left;
      }
    else
     {
     current = current->right;
     }
   if (current == NULL)
     {
    return 0;
     }
   }
return 1;
}
void inorder(struct Node *root)
{
 if (root != NULL)
  {
   inorder(root->left);
   cout << root->value << " ";
   inorder(root->right);
  }
}
struct Node *deleteNode(struct Node *node, int value)
{
 if (node == NULL)
  {
   return node;
  }
 if (value < node->value)
  {
   node->left = deleteNode(node->left, value);
  }
else if (value > node->value)
 {
   node->right = deleteNode(node->right, value);
 }
else
{
if (node->left == NULL)
 {
 struct Node *temp = node->right;
 free(node);
 return temp;
 }
 else if (node->right == NULL)
 {
 struct Node *temp = node->left;
 free(node);
 return temp;
  }
 struct Node *temp = successor(node->right);
 node->value = temp->value;
 node->right = deleteNode(node->right, temp->value);
}
return node;
}
int main()
 {
  struct Node *root = NULL;
  root = insert(root, 8);
  root = insert(root, 4);
  root = insert(root, 12);
  root = insert(root, 2);
  root = insert(root, 6);
  root = insert(root, 10);
  root = insert(root, 14);
  root = insert(root, 1);
  root = insert(root, 3);
  root = insert(root, 5);
  root = insert(root, 7);
  root = insert(root, 9);
  root = insert(root, 11);
  root = insert(root, 13);
  root = insert(root, 15);

 cout << "InOrder Traversal after inserting all nodes: " << endl;
 inorder(root);
 root = insert(root, -10);
 cout << "\nInOrder Traversal after inserting -10 : " << endl;
 inorder(root);
 cout << "\nSearching -5 in the BST: " << searchInBST(root, -5) << endl;
 cout << "Searching -10 in the BST: " << searchInBST(root, -10) << endl;
 root = deleteNode(root,8);
 cout<<"After deleting node 8, inorder traversal: "<<endl;
 inorder(root);
 root = deleteNode(root,-10);
 cout<<"\nAfter deleting node -10, inorder traversal: "<<endl;
 inorder(root);
}

Izlaz:

InOrder Traversal after inserting all nodes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

InOrder Traversal after inserting -10 :
10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Searching -5 in the BST: 0
Searching -10 in the BST: 1

After deleting node 8, inorder traversal:
-10 1 2 3 4 5 6 7 9 10 11 12 13 14 15

After deleting node -10, inorder traversal:
1 2 3 4 5 6 7 9 10 11 12 13 14 15

Implementacija binarnog stabla u Python

class Node:
def __init__(self,value):
      self.left = None
      self.right = None
      self.value = value
def insert(root,value):
      if root == None:
          return Node(value)
      if value< root.value:
          root.left = insert(root.left,value)
      else:
          root.right = insert(root.right,value)
          return root
  def searchInBST(root,value):
      current = root
  while current.value != value:
  if current.value > value:
      current = current.left
  else:
      current = current.right
  if current == None:
      return "Not found"
      return "Found"
def inorder(root):
    if root != None:
      inorder(root.left)
      print(root.value,end=" ")
      inorder(root.right)
def successor(root):
    present = root
    while present != None and present.left != None:
    present = present.left
      return present
def deleteNode(root,value):
    if root == None:
      return root
    if value < root.value:
        root.left = deleteNode(root.left, value)
    elif value>root.value:
        root.right = deleteNode(root.right, value)
    else:
    if root.left == None:
        temp = root.right
        root = None
        return temp
    elif root.right == None:
        temp = root.left
        root = None
        return temp
        temp = successor(root.right)
        root.value = temp.value
        root.right = deleteNode(root.right, temp.value)
        return root
        root = Node(8)
        root = insert(root, 4)
        root = insert(root, 12)
        root = insert(root, 2)
        root = insert(root, 6)
        root = insert(root, 10)
        root = insert(root, 14)
        root = insert(root, 1)
        root = insert(root, 3)
        root = insert(root, 5)
        root = insert(root, 7)
        root = insert(root, 9)
        root = insert(root, 11)
        root = insert(root, 13)
        root = insert(root, 15)
  print("InOrder Traversal after inserting all nodes: ")
  inorder(root)
  root = insert(root, -10)
  print("\nInOrder Traversal after inserting -10 : ")
  inorder(root)
  print("\nSearching -5 in the BST: ",searchInBST(root, -5))
  print("Searching -5 in the BST: ",searchInBST(root, -10))
  root = deleteNode(root,8)
  print("After deleting node 8, inorder traversal:")
  inorder(root)
  root = deleteNode(root,-10)
  print("\nAfter deleting node -10, inorder traversal:")
  inorder(root)

Izlaz:

InOrder Traversal after inserting all nodes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 

InOrder Traversal after inserting -10 : -10 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 

Searching -5 in the BST: Not found 

Searching -5 in the BST: Found After deleting node 8, inorder traversal: -10 1 2 3 4 5 6 7 9 10 11 12 13 14 15 

After deleting node -10, inorder traversal: 1 2 3 4 5 6 7 9 10 11 12 13 14 15

Primjena binarnog stabla

Evo nekih uobičajenih primjena binarnog stabla:

  • Organiziranje podataka o čvorovima poredanim redoslijedom
  • Koristi se u objektima mapiranja i postavljanja čvorova u bibliotekama programskih jezika.
  • Traženje elemenata u strukturama podataka

» Saznajte o našem sljedećem vodiču Algoritam kombinacije