Binärbaum in Datenstruktur (BEISPIEL)

Was ist ein Binärbaum?

Das Wort binär bedeutet zwei. In der Baumdatenstruktur bezeichnet „Binärbaum“ einen Baum, in dem jeder Knoten maximal zwei untergeordnete Knoten (linker und rechter Knoten) haben kann. Es ist ein einfacher Binärbaum.

Es gibt jedoch einen anderen Binärbaum, der am häufigsten verwendet wird und mehrere Anwendungsfälle hat. Er heißt Binärer Suchbaum (BST). Dieser Baum kann den Suchalgorithmus deutlich beschleunigen, genauer gesagt mit einer log(n)-Zeitkomplexität. In der Datenstruktur steht n für die Anzahl der Knoten im Binärbaum.

Was sind die Unterschiede zwischen Binärbaum und Binärsuchbaum?

Der Unterschied zwischen dem BST und dem regulären Binärbaum besteht darin, dass der linke BST-Knoten einen kleineren Wert als der Wurzelknoten und der rechte Knoten einen größeren Wert als der Wurzelknoten hat. Der linke Teilbaum enthält also immer einen kleineren Wert als die Wurzel, und der rechte Teilbaum enthält immer einen größeren Wert als die Wurzel.

Die Unterschiede zwischen Binärbaum und Binärsuchbaum

Beispiel für binäre Suchbäume

Lassen Sie uns das Konzept des binären Suchbaums anhand des folgenden Beispiels demonstrieren.

Beispiel für binäre Suchbäume

Hier können Sie alle Knoten der vorgegebenen Disziplin folgen. Es gibt eine Formel für die maximale Anzahl von Knoten im binären Suchbaum. Wenn wir den obigen Baum betrachten, können wir sehen, dass jeder Knoten außer allen Blattknoten zwei untergeordnete Knoten hat. Und die Höhe (h) des angegebenen Binärbaums beträgt 4. Die Formel lautet 2h - 1. Es ergibt also 15.

Beispiel für binäre Suchbäume

Beispiel für binäre Suchbäume

Das oben dargestellte Bild ist kein vollständiger Binärbaum oder ausgeglichener Binärbaum, sondern wird als vollständiger Binärbaum oder ausgeglichener Binärbaum bezeichnet. Es gibt eine andere Datenstruktur namens AVL (eine andere Art von Binärbaum), die die Höhe des Binärbaums optimiert und die Suche nach dem BST schneller durchführt, wie in Abb. 3.

Versuchen Sie, die geordnete Durchquerung des oben angegebenen Binärbaums zu berechnen. Sie werden feststellen, dass Sie ein nicht abnehmendes sortiertes Array erhalten und die Durchquerungsalgorithmen dieselben sind wie beim Binärbaum.

Arten von Binärbäumen

Hier sind einige wichtige Arten von Binärbäumen:

  • Vollständiger Binärbaum: Jeder Knoten in diesem Binärbaum kann 0 oder 2 untergeordnete Knoten haben. In dieser Art von Binärbaum ist nur ein untergeordneter Knoten nicht zulässig. Mit Ausnahme des Blattknotens haben also alle Knoten zwei untergeordnete Knoten.

Arten von Binärbäumen

  • Vollständiger Binärbaum: Jeder Knoten kann 0 oder 2 Knoten haben. Es sieht aus wie der vollständige Binärbaum, aber alle Blattelemente sind zum linken Teilbaum geneigt, wohingegen sich im vollständigen Binärbaum Knoten im rechten oder linken Teilbaum befinden können.

Arten von Binärbäumen

  • Perfekter Binärbaum: Alle Knoten müssen 0 oder 2 Knoten haben und alle Blattknoten sollten sich auf derselben Ebene oder Höhe befinden. Das obige Beispiel einer vollständigen Binärbaumstruktur ist kein perfekter Binärbaum, da Knoten 6 und Knoten 1,2,3 nicht auf derselben Höhe liegen. Aber das Beispiel des vollständigen Binärbaums ist ein perfekter Binärbaum.
  • Entarteter Binärbaum: Jeder Knoten kann nur ein einziges Kind haben. Alle Operationen wie Suchen, Einfügen und Löschen dauern O(N) Zeit.

Arten von Binärbäumen

  • Ausgeglichener Binärbaum: In diesem Binärbaum beträgt der Höhenunterschied zwischen linkem und rechtem Teilbaum höchstens 1. Wenn wir also einen Knoten hinzufügen oder löschen, müssen wir die Höhe des Baums wieder ausgleichen. Diese Art von selbstausgeglichenem Binärbaum wird als „Self-Balanced Binary Tree“ bezeichnet AVL-Baum.

Arten von Binärbäumen

Es gibt drei grundlegende BST-Operationen. Diese werden im Folgenden ausführlich erläutert.

Implementierung eines binären Baums in C und 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);
}

Ausgang:

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

Implementierung des Binärbaums in 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)

Ausgang:

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

Anwendung des Binärbaums

Hier sind einige häufige Anwendungen von Binary Tree:

  • Knotendaten in sortierter Reihenfolge organisieren
  • Wird in Map- und Set-Node-Objekten in Programmiersprachenbibliotheken verwendet.
  • Suchen nach Elementen in den Datenstrukturen

» Erfahren Sie in unserem nächsten Tutorial mehr über Kombinationsalgorithmus