{"id":30530,"date":"2019-10-31T21:36:01","date_gmt":"2019-10-31T18:36:01","guid":{"rendered":"https:\/\/prohoster.info\/blog\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska\/"},"modified":"2019-10-31T21:36:01","modified_gmt":"2019-10-31T18:36:01","slug":"binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","title":{"rendered":"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h2>Einf\u00fchrung<\/h2>\n<p>\nDieser Artikel befasst sich mit bin\u00e4ren Suchb\u00e4umen. K\u00fcrzlich habe ich einen Artikel \u00fcber <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/438512\/\">Datenkompression mit dem Huffman-Verfahren geschrieben.<\/a><\/noindex> Dabei habe ich nicht viel auf bin\u00e4re B\u00e4ume geachtet, da die Methoden zum Suchen, Einf\u00fcgen und L\u00f6schen nicht relevant waren. Jetzt habe ich beschlossen, einen Artikel genau \u00fcber B\u00e4ume zu schreiben. Fangen wir an. <\/p>\n<p>Ein Baum ist eine Datenstruktur, die aus Knoten besteht, die durch Kanten verbunden sind. Man kann sagen, dass ein Baum ein Spezialfall eines Grafen ist. Hier ist ein Beispiel f\u00fcr einen Baum: <\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt\" src=\"\/wp-content\/uploads\/2019\/03\/502ac27f1b93f926c68a68777f6bddd7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDas ist kein bin\u00e4rer Suchbaum! Alles unter dem Cut!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Terminologie<\/h2>\n<p><\/p>\n<h4>Wurzel<\/h4>\n<p>\n<i>Die Wurzel des Baumes<\/i> ist der oberste Knoten. In unserem Beispiel ist das der Knoten A. Im Baum kann von der Wurzel zu jedem anderen Knoten nur ein Weg f\u00fchren! Tats\u00e4chlich kann jeder Knoten als Wurzel des entsprechenden Teilbaums betrachtet werden.<\/p>\n<h4>Eltern\/Kinder<\/h4>\n<p>\nAlle Knoten au\u00dfer der Wurzel haben genau eine Kante, die nach oben zu einem anderen Knoten f\u00fchrt. Der Knoten, der \u00fcber dem aktuellen Knoten liegt, wird <i>Elternteil<\/i> dieses Knotens genannt. Der Knoten, der unter dem aktuellen Knoten liegt und mit diesem verbunden ist, wird <i>Kind<\/i> dieses Knotens genannt. Lassen Sie uns ein Beispiel nehmen. Nehmen wir den Knoten B, dann wird sein Elternteil der Knoten A sein, und seine Kinder sind die Knoten D, E und F.<\/p>\n<h4>Blatt<\/h4>\n<p>\nEin Knoten, der keine Kinder hat, wird als Blatt des Baumes bezeichnet. In unserem Beispiel sind die Bl\u00e4tter die Knoten D, E, F, G, I, J, K.<\/p>\n<p>Das ist die grundlegende Terminologie. Weitere Begriffe werden sp\u00e4ter behandelt. Ein bin\u00e4rer Baum ist ein Baum, in dem jeder Knoten nicht mehr als zwei Kinder haben kann. Wie Sie erraten haben, wird der Baum aus dem Beispiel kein bin\u00e4rer Baum sein, da die Knoten B und H mehr als zwei Kinder haben. Hier ist ein Beispiel f\u00fcr einen bin\u00e4ren Baum:<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt\" src=\"\/wp-content\/uploads\/2019\/03\/2f587bd1c428d3850cb0163d6c2984a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn den Knoten eines Baumes kann jede Art von Information gespeichert werden. Ein bin\u00e4rer Suchbaum ist ein bin\u00e4rer Baum, der die folgenden Eigenschaften aufweist:<\/p>\n<ol>\n<li>Beide Teilb\u00e4ume \u2013 der linke und der rechte \u2013 sind bin\u00e4re Suchb\u00e4ume.<\/li>\n<li>Bei allen Knoten des linken Teilbaums eines beliebigen Knotens X sind die Werte der Schl\u00fcsseldaten kleiner als der Wert des Schl\u00fcssels des Knotens X selbst.<\/li>\n<li>Bei allen Knoten des rechten Teilbaums eines beliebigen Knotens X sind die Werte der Schl\u00fcsseldaten gr\u00f6\u00dfer oder gleich dem Wert des Schl\u00fcssels des Knotens X selbst. <\/li>\n<\/ol>\n<p><i>Schl\u00fcssel<\/i> - eine bestimmte Eigenschaft des Knotens (zum Beispiel eine Zahl). Der Schl\u00fcssel ist n\u00f6tig, um das Element des Baumes zu finden, das diesem Schl\u00fcssel entspricht. Beispiel f\u00fcr einen bin\u00e4ren Suchbaum:<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt\" src=\"\/wp-content\/uploads\/2019\/03\/a70ca7d2fdf289b5d1e14bdb4bc38b00.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Baumdarstellung<\/h2>\n<p>\nIm Verlauf werde ich einige (m\u00f6glicherweise unvollst\u00e4ndige) Codeabschnitte anf\u00fchren, um Ihr Verst\u00e4ndnis zu verbessern. Der vollst\u00e4ndige Code wird am Ende des Artikels zu finden sein. <\/p>\n<p>Ein Baum besteht aus Knoten. Die Struktur eines Knotens:<\/p>\n<pre><code class=\"java\">public class Node {\n    private T data;\n    private int key;\n    private Node leftChild;\n    private Node rightChild;\n\n    public Node(T data, int key) {\n        this.data = data;\n        this.key = key;\n    }\n    public Node getLeftChild() {\n        return leftChild;\n    }\n\n    public Node getRightChild() {\n        return rightChild;\n    }\n\/\/... weitere Methoden des Knotens\n}\n<\/code><\/pre>\n<p>\nJeder Knoten hat zwei Nachkommen (es ist durchaus m\u00f6glich, dass der Nachfolger leftChild und\/oder rightChild den Wert null enthalten). Sie haben wahrscheinlich verstanden, dass in diesem Fall die Zahl data \u2013 die Daten, die im Knoten gespeichert sind; key \u2013 der Schl\u00fcssel des Knotens ist.<\/p>\n<p>Mit dem Knoten haben wir uns besch\u00e4ftigt, jetzt lassen Sie uns \u00fcber dr\u00e4ngende Probleme von B\u00e4umen sprechen. Hier und im Folgenden wird unter dem Begriff \u201eBaum\u201c das Konzept eines bin\u00e4ren Suchbaums verstanden. Die Struktur eines bin\u00e4ren Baumes:<\/p>\n<pre><code class=\"java\">public class BinaryTree {\n     private Node root;\n\n    \/\/ Methoden des Baumes\n}\n<\/code><\/pre>\n<p>Als Klassenfeld ben\u00f6tigen wir nur die Wurzel des Baumes, denn von der Wurzel aus kann man mit Hilfe der Methoden getLeftChild() und getRightChild() zu jedem Knoten des Baumes gelangen.<\/p>\n<h2>Algorithmen im Baum<\/h2>\n<p><\/p>\n<h3>Die Suche<\/h3>\n<p>\nAngenommen, Sie haben einen Baum konstruiert. Wie finden Sie ein Element mit dem Schl\u00fcssel key? Sie m\u00fcssen nacheinander vom Wurzelknoten nach unten durch den Baum gehen und den Wert key mit dem Schl\u00fcssel des aktuellen Knotens vergleichen: wenn key kleiner ist als der Schl\u00fcssel des aktuellen Knotens, gehen Sie zum linken Nachkommen des Knotens, wenn gr\u00f6\u00dfer \u2013 zum rechten, wenn die Schl\u00fcssel gleich sind \u2013 der gesuchte Knoten ist gefunden! Der entsprechende Code lautet:<\/p>\n<pre><code class=\"java\">public Node find(int key) {\n    Node current = root;\n    while (current.getKey() != key) {\n        if (key &lt; current.getKey())\n            current = current.getLeftChild();\n        else\n            current = current.getRightChild();\n        if (current == null)\n            return null;\n    }\n    return current;\n}\n<\/code><\/pre>\n<p>\nWenn current gleich null wird, bedeutet dies, dass die Durchsuchung das Ende des Baumes erreicht hat (auf konzeptioneller Ebene befinden Sie sich an einem nicht existierenden Ort des Baumes \u2013 dem Nachkommen eines Blattes).<\/p>\n<p>Betrachten wir die Effizienz des Suchalgorithmus in einem ausgewogenen Baum (einem Baum, in dem die Knoten mehr oder weniger gleichm\u00e4\u00dfig verteilt sind). Dann betr\u00e4gt die Effizienz der Suche O(log(n)), wobei der Logarithmus zur Basis 2 ist. Siehe: Wenn der ausgewogene Baum n Elemente hat, bedeutet das, dass es log(n) zur Basis 2 Ebenen im Baum geben wird. Und bei der Suche steigen Sie in einem Schritt der Schleife um ein Level ab.<\/p>\n<h3>Einf\u00fcgen<\/h3>\n<p>\nWenn Sie das Wesen der Suche verstanden haben, wird es Ihnen leichtfallen, die Einf\u00fcgung zu verstehen. Sie m\u00fcssen einfach zum Blatt des Baumes hinuntergehen (nach den in der Suche beschriebenen Absteigregeln) und dessen Nachkomme werden \u2013 links oder rechts, je nach Schl\u00fcssel. Implementierung:<\/p>\n<pre><code class=\"java\">   public void insert(T insertData, int key) {\\n        Node current = root;\\n        Node parent;\\n        Node newNode = new Node(insertData, key);\\n        if (root == null)\\n            root = newNode;\\n        else {\\n            while (true) {\\n                parent = current;\\n                if (key &lt; current.getKey()) {\\n                    current = current.getLeftChild();\\n                    if (current == null) {\\n                         parent.setLeftChild(newNode);\\n                         return;\\n                    }\\n                }\\n                else {\\n                    current = current.getRightChild();\\n                    if (current == null) {\\n                        parent.setRightChild(newNode);\\n                        return;\\n                    }\\n                }\\n            }\\n        }\\n    }\n<\/code><\/pre>\n<p>\nIn diesem Fall m\u00fcssen wir, neben dem aktuellen Knoten, Informationen \u00fcber den Elter des aktuellen Knotens speichern. Wenn current null wird, wird in der Variable parent das ben\u00f6tigte Blatt liegen. <br \/>\nDie Effizienz der Einf\u00fcgung wird offensichtlich die gleiche sein wie die der Suche \u2013 O(log(n)).<\/p>\n<h3>L\u00f6schen<\/h3>\n<p>\nDas L\u00f6schen ist die komplexeste Operation, die mit dem Baum durchgef\u00fchrt werden muss. Zun\u00e4chst muss das Element gefunden werden, das wir l\u00f6schen m\u00f6chten. Aber was dann? Wenn wir einfach den Wert null zu seiner Referenz zuweisen, verlieren wir die Informationen \u00fcber den Teilbaum, dessen Wurzel dieser Knoten ist. Die Methoden zum L\u00f6schen von B\u00e4umen unterscheiden sich in drei F\u00e4lle.<\/p>\n<h4>Erster Fall. Der zu l\u00f6schende Knoten hat keine Nachkommen.<\/h4>\n<p>\nWenn der zu l\u00f6schende Knoten keine Nachkommen hat, bedeutet das, dass er ein Blatt ist. Folglich k\u00f6nnen wir einfach den Feldern leftChild oder rightChild seines Elternteils den Wert null zuweisen. <\/p>\n<h4>Zweiter Fall. Der zu l\u00f6schende Knoten hat einen Nachkommen.<\/h4>\n<p>\nDieser Fall ist auch nicht sehr kompliziert. Kehren wir zu unserem Beispiel zur\u00fcck. Angenommen, wir m\u00fcssen das Element mit dem Schl\u00fcssel 14 l\u00f6schen. Sie werden zustimmen, dass, da es ein rechter Nachkomme des Knotens mit dem Schl\u00fcssel 10 ist, jeder seiner Nachkommen (in diesem Fall der rechte) einen Schl\u00fcssel gr\u00f6\u00dfer als 10 haben wird. Daher k\u00f6nnen wir es leicht aus dem Baum 'heraus schneiden', und den Elternknoten direkt mit dem Nachkommen des zu l\u00f6schenden Knotens verbinden, d.h. den Knoten mit dem Schl\u00fcssel 10 mit dem Knoten 13 verbinden. Eine \u00e4hnliche Situation g\u00e4be es, wenn wir einen Knoten l\u00f6schen m\u00fcssten, der ein linker Nachkomme seines Elternteils ist. Denken Sie selbst dar\u00fcber nach \u2013 es ist eine genaue Analogie. <\/p>\n<h4>Dritter Fall. Der Knoten hat zwei Nachkommen.<\/h4>\n<p>\nDer komplizierteste Fall. Lassen Sie uns an einem neuen Beispiel untersuchen.<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt\" src=\"\/wp-content\/uploads\/2019\/03\/0d600478e4a046ae6f7267be49b231bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>Suche nach dem Nachfolger.<\/h4>\n<p>\n Angenommen, wir m\u00fcssen einen Knoten mit dem Schl\u00fcssel 25 l\u00f6schen. Wen setzen wir an seine Stelle? Jemand aus seinen Nachfolgern (Nachkommen oder Nachkommen von Nachkommen) muss der <i>Nachfolger<\/i>(derjenige, der den Platz des gel\u00f6schten Knotens einnimmt). <\/p>\n<p>Wie versteht man, wer Nachfolger werden soll? Intuitiv ist klar, dass dies ein Knoten im Baum ist, dessen Schl\u00fcssel der n\u00e4chstgr\u00f6\u00dfere vom gel\u00f6schten Knoten ist. Der Algorithmus besteht darin, dass wir zu seinem rechten Nachkommen (immer zum rechten, da bereits gesagt wurde, dass der Schl\u00fcssel des Nachfolgers gr\u00f6\u00dfer als der Schl\u00fcssel des gel\u00f6schten Knotens ist) wechseln und dann die Kette der linken Nachkommen dieses rechten Nachkommens durchlaufen. In unserem Beispiel m\u00fcssen wir zum Knoten mit dem Schl\u00fcssel 35 wechseln und dann bis zum Blatt der Kette seiner linken Nachkommen hinuntergehen \u2013 in diesem Fall besteht diese Kette nur aus dem Knoten mit dem Schl\u00fcssel 30. Streng genommen suchen wir den kleinsten Knoten in der Menge der Knoten, die gr\u00f6\u00dfer sind als der gesuchte Knoten.<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt\" src=\"\/wp-content\/uploads\/2019\/03\/50c4e3e49111eec9e1fd13083ee9b9b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nCode des Nachfolgerfindungsalgorithmus:<\/p>\n<pre><code class=\"java\">    public Node getSuccessor(Node deleteNode) {\n        Node parentSuccessor = deleteNode; \/\/ Elternteil des Nachfolgers\n        Node successor = deleteNode; \/\/ Nachfolger\n        Node current = successor.getRightChild(); \/\/ einfach ein \"laufender\" Knoten\n        while (current != null) {\n            parentSuccessor = successor;\n            successor = current;\n            current = current.getLeftChild();\n        }\n        \/\/ Beim Verlassen der Schleife haben wir den Nachfolger und den Elternteil des Nachfolgers\n        if (successor != deleteNode.getRightChild()) { \/\/ wenn der Nachfolger nicht mit dem rechten Nachkommen des gel\u00f6schten Knotens \u00fcbereinstimmt\n            parentSuccessor.setLeftChild(successor.getRightChild()); \/\/ dann \u00fcbernimmt sein Elternteil den Nachkommen des Nachfolgers, um ihn nicht zu verlieren\n            successor.setRightChild(deleteNode.getRightChild()); \/\/ verbinden den Nachfolger mit dem rechten Nachkommen des gel\u00f6schten Knotens\n        }\n        return successor;\n    }\n<\/code><\/pre>\n<p>\nVollst\u00e4ndiger Code der Methode delete:<\/p>\n<pre><code class=\"java\">public boolean delete(int deleteKey) {\n        Node current = root;\n        Node parent = current;\n        boolean isLeftChild = false; \/\/ Abh\u00e4ngig davon, ob der zu l\u00f6schende Knoten ein linkes oder rechtes Kind seines Elternteils ist, wird die boolesche Variable isLeftChild entweder true oder false annehmen.\n        while (current.getKey() != deleteKey) {\n            parent = current;\n            if (deleteKey &lt; current.getKey()) {\n                current = current.getLeftChild();\n                isLeftChild = true;\n            } else {\n                isLeftChild = false;\n                current = current.getRightChild();\n            }\n            if (current == null)\n                return false;\n        }\n\n        if (current.getLeftChild() == null &amp;&amp; current.getRightChild() == null) { \/\/ erster Fall\n            if (current == root)\n                current = null;\n            else if (isLeftChild)\n                parent.setLeftChild(null);\n            else\n                parent.setRightChild(null);\n        } else if (current.getRightChild() == null) { \/\/ zweiter Fall\n            if (current == root)\n                root = current.getLeftChild();\n            else if (isLeftChild)\n                parent.setLeftChild(current.getLeftChild());\n            else\n                current.setRightChild(current.getLeftChild());\n        } else if (current.getLeftChild() == null) {\n            if (current == root)\n                root = current.getRightChild();\n            else if (isLeftChild)\n                parent.setLeftChild(current.getRightChild());\n            else\n                parent.setRightChild(current.getRightChild());\n        } \n        else { \/\/ dritter Fall\n            Node successor = getSuccessor(current);\n            if (current == root)\n                root = successor;\n            else if (isLeftChild)\n                parent.setLeftChild(successor);\n            else\n                parent.setRightChild(successor);\n        }\n        return true;\n    }\n<\/code><\/pre>\n<p>\nDie Komplexit\u00e4t kann auf O(log(n)) abgesch\u00e4tzt werden.<\/p>\n<h3>Suche nach dem Maximum\/Minimum im Baum<\/h3>\n<p>\nOffensichtlich, um den minimalen\/maximalen Wert im Baum zu finden \u2013 man muss der Reihe nach die Kette der linken\/rechten Elemente des Baums durchlaufen; wenn man den Blatt erreicht, ist dieser der minimale\/maximale Element.<\/p>\n<pre><code class=\"java\">    public Node getMinimum(Node startPoint) {\n        Node current = startPoint;\n        Node parent = current;\n        while (current != null) {\n            parent = current;\n            current = current.getLeftChild();\n        }\n        return parent;\n    }\n\n    public Node getMaximum(Node startPoint) {\n        Node current = startPoint;\n        Node parent = current;\n        while (current != null) {\n            parent = current;\n            current = current.getRightChild();\n        }\n        return parent;\n    }\n<\/code><\/pre>\n<p>\nDie Komplexit\u00e4t ist O(log(n))<\/p>\n<h3>Symmetrische Traversierung<\/h3>\n<p>\nTraversal \u2013 jeder Knoten des Baumes wird besucht, um eine Aktion mit ihm durchzuf\u00fchren.<\/p>\n<p>Algorithmus der rekursiven symmetrischen Traversierung:<\/p>\n<ol>\n<li>Aktion mit dem linken Kind durchf\u00fchren<\/li>\n<li>Aktion mit sich selbst durchf\u00fchren<\/li>\n<li>Aktion mit dem rechten Kind durchf\u00fchren<\/li>\n<\/ol>\n<p>\nCode:<\/p>\n<pre><code class=\"java\">    public void inOrder(Node current) {\n        if (current != null) {\n            inOrder(current.getLeftChild());\n            System.out.println(current.getData() + \" \");\/\/Hier kann alles M\u00f6gliche stehen\n            inOrder(current.getRightChild());\n        }\n    }\n<\/code><\/pre>\n<p><\/p>\n<h2>Fazit<\/h2>\n<p>\nEndlich! Wenn ich etwas unklar ausgedr\u00fcckt habe oder es Anmerkungen gibt, erwarte ich diese in den Kommentaren. Wie versprochen, hier ist der vollst\u00e4ndige Code.<\/p>\n<p>Node.java:<\/p>\n<pre><code class=\"java\">public class Node {\n    private T data;\n    private int key;\n    private Node leftChild;\n    private Node rightChild;\n\n    public Node(T data, int key) {\n        this.data = data;\n        this.key = key;\n    }\n\n    public void setLeftChild(Node newNode) {\n        leftChild = newNode;\n    }\n\n    public void setRightChild(Node newNode) {\n        rightChild = newNode;\n    }\n\n    public Node getLeftChild() {\n        return leftChild;\n    }\n\n    public Node getRightChild() {\n        return rightChild;\n    }\n\n    public T getData() {\n        return data;\n    }\n\n    public int getKey() {\n        return key;\n    }\n}\n\n<\/code><\/pre>\n<p>\nBinaryTree.java:<\/p>\n<pre><code class=\"java\">public class BinaryTree&lt;T&gt; {\n    private Node&lt;T&gt; root;\n\n    public Node&lt;T&gt; find(int key) {\n        Node&lt;T&gt; current = root;\n        while (current.getKey() != key) {\n            if (key &lt; current.getKey())\n                current = current.getLeftChild();\n            else\n                current = current.getRightChild();\n            if (current == null)\n                return null;\n        }\n        return current;\n    }\n\n    public void insert(T insertData, int key) {\n        Node&lt;T&gt; current = root;\n        Node&lt;T&gt; parent;\n        Node&lt;T&gt; newNode = new Node&lt;&gt;(insertData, key);\n        if (root == null)\n            root = newNode;\n        else {\n            while (true) {\n                parent = current;\n                if (key &lt; current.getKey()) {\n                    current = current.getLeftChild();\n                    if (current == null) {\n                         parent.setLeftChild(newNode);\n                         return;\n                    }\n                }\n                else {\n                    current = current.getRightChild();\n                    if (current == null) {\n                        parent.setRightChild(newNode);\n                        return;\n                    }\n                }\n            }\n        }\n    }\n\n    public Node&lt;T&gt; getMinimum(Node&lt;T&gt; startPoint) {\n        Node&lt;T&gt; current = startPoint;\n        Node&lt;T&gt; parent = current;\n        while (current != null) {\n            parent = current;\n            current = current.getLeftChild();\n        }\n        return parent;\n    }\n\n    public Node&lt;T&gt; getMaximum(Node&lt;T&gt; startPoint) {\n        Node&lt;T&gt; current = startPoint;\n        Node&lt;T&gt; parent = current;\n        while (current != null) {\n            parent = current;\n            current = current.getRightChild();\n        }\n        return parent;\n    }\n\n    public Node&lt;T&gt; getSuccessor(Node&lt;T&gt; deleteNode) {\n        Node&lt;T&gt; parentSuccessor = deleteNode;\n        Node&lt;T&gt; successor = deleteNode;\n        Node&lt;T&gt; current = successor.getRightChild();\n        while (current != null) {\n            parentSuccessor = successor;\n            successor = current;\n            current = current.getLeftChild();\n        }\n\n        if (successor != deleteNode.getRightChild()) {\n            parentSuccessor.setLeftChild(successor.getRightChild());\n            successor.setRightChild(deleteNode.getRightChild());\n        }\n        return successor;\n    }\n\n    public boolean delete(int deleteKey) {\n        Node&lt;T&gt; current = root;\n        Node&lt;T&gt; parent = current;\n        boolean isLeftChild = false;\n        while (current.getKey() != deleteKey) {\n            parent = current;\n            if (deleteKey &lt; current.getKey()) {\n                current = current.getLeftChild();\n                isLeftChild = true;\n            } else {\n                isLeftChild = false;\n                current = current.getRightChild();\n            }\n            if (current == null)\n                return false;\n        }\n\n        if (current.getLeftChild() == null &amp;&amp; current.getRightChild() == null) {\n            if (current == root)\n                current = null;\n            else if (isLeftChild)\n                parent.setLeftChild(null);\n            else\n                parent.setRightChild(null);\n        }\n        else if (current.getRightChild() == null) {\n            if (current == root)\n                root = current.getLeftChild();\n            else if (isLeftChild)\n                parent.setLeftChild(current.getLeftChild());\n            else\n                current.setRightChild(current.getLeftChild());\n        } else if (current.getLeftChild() == null) {\n            if (current == root)\n                root = current.getRightChild();\n            else if (isLeftChild)\n                parent.setLeftChild(current.getRightChild());\n            else\n                parent.setRightChild(current.getRightChild());\n        } \n        else {\n            Node&lt;T&gt; successor = getSuccessor(current);\n            if (current == root)\n                root = successor;\n            else if (isLeftChild)\n                parent.setLeftChild(successor);\n            else\n                parent.setRightChild(successor);\n        }\n        return true;\n    }\n\n    public void inOrder(Node&lt;T&gt; current) {\n        if (current != null) {\n            inOrder(current.getLeftChild());\n            System.out.println(current.getData() + \" \");\n            inOrder(current.getRightChild());\n        }\n    }\n}\n<\/code><\/pre>\n<h2>P.S.<\/h2>\n<p><\/p>\n<h3>Degeneration bis O(n)<\/h3>\n<p>\nViele von Ihnen haben vielleicht bemerkt: Was w\u00e4re, wenn das Baumstruktur unausgewogen wird? Zum Beispiel, indem man Knoten mit aufsteigenden Schl\u00fcsseln in den Baum einf\u00fcgt: 1,2,3,4,5,6\u2026 Dann \u00e4hnelt der Baum etwas einer verketteten Liste. Und ja, der Baum verliert seine baumartige Struktur, was zu einer Verringerung der Effizienz beim Datenzugriff f\u00fchrt. Die Komplexit\u00e4t von Such-, Einf\u00fcge- und L\u00f6schoperationen wird gleich der einer verketteten Liste sein: O(n). Dies ist einer der wichtigsten, meiner Meinung nach, Nachteile von bin\u00e4ren B\u00e4umen.<\/p>\n<p class=\"for_users_only_msg\">Nur registrierte Benutzer k\u00f6nnen an der Umfrage teilnehmen. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Bitte einloggen<\/a><\/noindex>.<\/p>\n<h2 class=\"default-block__polling-title\">Ich bin noch nicht lange auf Habr\u00e9, und ich w\u00fcrde gerne wissen, \u00fcber welche Themen Sie mehr Artikel sehen m\u00f6chten?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Datenstrukturen<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Algorithmen (DP, Rekursion, Datenkompression usw.)<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Anwendung von Datenstrukturen und Algorithmen im echten Leben<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programmierung von Android-Anwendungen in Java<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programmierung von Webanwendungen in Java<\/p>\n<\/li>\n<\/ul>\n<p>    2 Benutzer haben abgestimmt. 1 Benutzer hat sich enthalten.<br \/>\n<br \/>Quelle: habr.com<\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u043b\u044e\u0434\u0438\u044f \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c \u043f\u043e\u0438\u0441\u043a\u0430. \u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0434\u0435\u043b\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u044e \u043f\u0440\u043e \u0441\u0436\u0430\u0442\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0425\u0430\u0444\u0444\u043c\u0430\u043d\u0430. \u0422\u0430\u043c \u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0434\u0435\u0440\u0435\u0432\u044c\u044f, \u0438\u0431\u043e \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u0438\u0441\u043a\u0430, \u0432\u0441\u0442\u0430\u0432\u043a\u0438, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043d\u0435 \u0431\u044b\u043b\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b. \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e \u0434\u0435\u0440\u0435\u0432\u044c\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u043d\u0430\u0447\u043d\u0435\u043c. \u0414\u0435\u0440\u0435\u0432\u043e \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0430\u044f \u0438\u0437 \u0443\u0437\u043b\u043e\u0432, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u0440\u0435\u0431\u0440\u0430\u043c\u0438. \u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u0435\u0440\u0435\u0432\u043e \u2014 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22528,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-30530","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u043b\u044e\u0434\u0438\u044f \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c \u043f\u043e\u0438\u0441\u043a\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Binary Tree \u0438\u043b\u0438 \u043a\u0430\u043a \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u043e\u0438\u0441\u043a\u0430 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u043b\u044e\u0434\u0438\u044f \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c \u043f\u043e\u0438\u0441\u043a\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:36:01+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:36:01+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Binary Tree oder wie man einen bin\u00e4ren Suchbaum erstellt | ProHoster","description":"Pr\u00e4ludium Dieser Artikel ist den bin\u00e4ren Suchb\u00e4umen gewidmet.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Binary Tree \u0438\u043b\u0438 \u043a\u0430\u043a \u043f\u0440\u0438\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u043f\u043e\u0438\u0441\u043a\u0430 | ProHoster","og:description":"\u041f\u0440\u0435\u043b\u044e\u0434\u0438\u044f \u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u0430 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c \u043f\u043e\u0438\u0441\u043a\u0430.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:36:01+00:00","article:modified_time":"2019-10-31T18:36:01+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30530","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 01:39:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:33:27","updated":"2026-01-21 01:39:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/30530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=30530"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/30530\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/22528"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=30530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=30530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=30530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}