{"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\/sl\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","title":{"rendered":"Binary Tree ali kako pripraviti binarno iskalno drevo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h2>Predigra<\/h2>\n<p>\nTa \u010dlenek je v\u011bnov\u00e1n bin\u00e1rn\u00edm vyhled\u00e1vac\u00edm strom\u016fm. Ned\u00e1vno jsem psal \u010dl\u00e1nek o <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/438512\/\">kompresi dat metodou Huffmana.<\/a><\/noindex> Tam jsem nev\u011bnoval mnoho pozornosti bin\u00e1rn\u00edm strom\u016fm, proto\u017ee metody vyhled\u00e1v\u00e1n\u00ed, vkl\u00e1d\u00e1n\u00ed a maz\u00e1n\u00ed nebyly aktu\u00e1ln\u00ed. Nyn\u00ed jsem se rozhodl napsat \u010dl\u00e1nek pr\u00e1v\u011b o stromech. Poj\u010fme za\u010d\u00edt. <\/p>\n<p>Strom je datov\u00e1 struktura slo\u017een\u00e1 z uzl\u016f, kter\u00e9 jsou spojeny hranami. Lze \u0159\u00edci, \u017ee strom je zvl\u00e1\u0161tn\u00edm p\u0159\u00edpadem grafu. Zde je p\u0159\u00edklad stromu: <\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree ali kako pripraviti binarno iskalno drevo\" src=\"\/wp-content\/uploads\/2019\/03\/502ac27f1b93f926c68a68777f6bddd7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo nen\u00ed bin\u00e1rn\u00ed vyhled\u00e1vac\u00ed strom! V\u0161e bude pod \u0161t\u00edtkem!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Terminologija<\/h2>\n<p><\/p>\n<h4>Ko\u0159en<\/h4>\n<p>\n<i>Ko\u0159en stromu<\/i> je nejvy\u0161\u0161\u00ed uzel. V p\u0159\u00edkladu je to uzel A. Ve strom\u011b m\u016f\u017ee od ko\u0159ene k jak\u00e9mukoli jin\u00e9mu uzlu v\u00e9st pouze jedna cesta! Ve skute\u010dnosti m\u016f\u017ee b\u00fdt jak\u00fdkoli uzel pova\u017eov\u00e1n za ko\u0159en p\u0159\u00edslu\u0161n\u00e9ho podstromu tohoto uzlu.<\/p>\n<h4>Rodi\u010de\/d\u011bti<\/h4>\n<p>\nV\u0161echny uzly krom\u011b ko\u0159enov\u00e9ho maj\u00ed p\u0159esn\u011b jednu hranu, kter\u00e1 vede nahoru k jin\u00e9mu uzlu. Uzel um\u00edst\u011bn\u00fd v\u00fd\u0161e ne\u017e aktu\u00e1ln\u00ed uzel se naz\u00fdv\u00e1 <i>rodi\u010d<\/i> tohoto uzlu. Uzel um\u00edst\u011bn\u00fd n\u00ed\u017ee ne\u017e aktu\u00e1ln\u00ed, a spojen\u00fd s n\u00edm, se naz\u00fdv\u00e1 <i>potomek<\/i> tohoto uzlu. Pod\u00edvejme se na p\u0159\u00edklad. Vezm\u011bme uzel B, pak jeho rodi\u010dem bude uzel A a potomky budou uzly D, E a F.<\/p>\n<h4>Sheet<\/h4>\n<p>\nUzel, kter\u00fd nem\u00e1 \u017e\u00e1dn\u00e9 potomky, se naz\u00fdv\u00e1 list stromu. V p\u0159\u00edkladu jsou listy uzly D, E, F, G, I, J, K.<\/p>\n<p>Toto jsou hlavn\u00ed term\u00edny. Dal\u0161\u00ed pojmy budou vysv\u011btleny pozd\u011bji. Tak\u017ee bin\u00e1rn\u00ed strom je strom, ve kter\u00e9m m\u00e1 ka\u017ed\u00fd uzel maxim\u00e1ln\u011b dva potomky. Jak jste asi uhodli, strom z p\u0159\u00edkladu nen\u00ed bin\u00e1rn\u00ed, proto\u017ee uzly B a H maj\u00ed v\u00edce ne\u017e dva potomky. Zde je p\u0159\u00edklad bin\u00e1rn\u00edho stromu:<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree ali kako pripraviti binarno iskalno drevo\" src=\"\/wp-content\/uploads\/2019\/03\/2f587bd1c428d3850cb0163d6c2984a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nU uzl\u016f stromu m\u016f\u017ee b\u00fdt jak\u00e1koli informace. Bin\u00e1rn\u00ed vyhled\u00e1vac\u00ed strom je bin\u00e1rn\u00ed strom, kter\u00fd m\u00e1 n\u00e1sleduj\u00edc\u00ed vlastnosti:<\/p>\n<ol>\n<li>Oba podstromy \u2013 lev\u00fd i prav\u00fd \u2013 jsou bin\u00e1rn\u00ed vyhled\u00e1vac\u00ed stromy.<\/li>\n<li>U v\u0161ech uzl\u016f lev\u00e9ho podstromu libovoln\u00e9ho uzlu X jsou hodnoty kl\u00ed\u010d\u016f dat men\u0161\u00ed ne\u017e hodnota kl\u00ed\u010de dat samotn\u00e9ho uzlu X.<\/li>\n<li>U v\u0161ech uzl\u016f prav\u00e9ho podstromu libovoln\u00e9ho uzlu X jsou hodnoty kl\u00ed\u010d\u016f dat v\u011bt\u0161\u00ed nebo rovny, ne\u017e hodnota kl\u00ed\u010de dat samotn\u00e9ho uzlu X. <\/li>\n<\/ol>\n<p><i>Opcija<\/i> \u2013 n\u011bjak\u00e1 charakteristika uzlu (nap\u0159\u00edklad \u010d\u00edslo). Kl\u00ed\u010d je pot\u0159ebn\u00fd k tomu, abychom mohli naj\u00edt prvek stromu, kter\u00e9mu tento kl\u00ed\u010d odpov\u00edd\u00e1. P\u0159\u00edklad bin\u00e1rn\u00edho vyhled\u00e1vac\u00edho stromu:<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree ali kako pripraviti binarno iskalno drevo\" src=\"\/wp-content\/uploads\/2019\/03\/a70ca7d2fdf289b5d1e14bdb4bc38b00.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Zobrazen\u00ed stromu<\/h2>\n<p>\nMed napredovanjem bom predstavil nekatere (morda nepopolne) kose kode, da bi izbolj\u0161al va\u0161e razumevanje. Celotna koda bo na koncu \u010dlanka. <\/p>\n<p>Drevo je sestavljeno iz vozli\u0161\u010d. Struktura vozli\u0161\u010da:<\/p>\n<pre><code class=\"java\">public class Node&lt;T&gt; {\n    private T data;\n    private int key;\n    private Node&lt;T&gt; leftChild;\n    private Node&lt;T&gt; rightChild;\n\n    public Node(T data, int key) {\n        this.data = data;\n        this.key = key;\n    }\n    public Node&lt;T&gt; getLeftChild() {\n        return leftChild;\n    }\n\n    public Node&lt;T&gt; getRightChild() {\n        return rightChild;\n    }\n\/\/...ostali metod vozli\u0161\u010da\n}\n<\/code><\/pre>\n<p>\nVsako vozli\u0161\u010de ima dva potomca (zelo verjetno, da bodo potomca leftChild in\/ali rightChild vsebovala vrednost null). Verjetno ste razumeli, da v tem primeru data predstavlja podatke, shranjene v vozli\u0161\u010du; key pa je klju\u010d vozli\u0161\u010da.<\/p>\n<p>Z vozli\u0161\u010dem smo se \u017ee seznanili, zdaj pa se pogovorimo o trenutnih te\u017eavah z drevesi. Tukaj in naprej bom pod izrazom 'drevo' razumel pojem binarnega iskalnega drevesa. Struktura binarnega drevesa:<\/p>\n<pre><code class=\"java\">public class BinaryTree&lt;T&gt; {\n     private Node&lt;T&gt; root;\n\n    \/\/metodi drevesa\n}\n<\/code><\/pre>\n<p>Kot \u010dlan razreda bomo potrebovali le koren drevesa, saj lahko od korena z metodama getLeftChild() in getRightChild() prispemo do katerega koli vozli\u0161\u010da drevesa.<\/p>\n<h2>Algoritmi v drevesu<\/h2>\n<p><\/p>\n<h3>Iskanje<\/h3>\n<p>\nRecimo, da imate zgrajeno drevo. Kako najti element s klju\u010dem key? Treba je zaporedno premikati od korena navzdol po drevesu in primerjati vrednost key s klju\u010dem trenutnega vozli\u0161\u010da: \u010de je key manj\u0161i od klju\u010da trenutnega vozli\u0161\u010da, preidite na levega potomca vozli\u0161\u010da, \u010de je ve\u010dji \u2014 na desnega, \u010de sta klju\u010da enaka \u2014 iskano vozli\u0161\u010de je najdeno! Ustrezna koda je:<\/p>\n<pre><code class=\"java\">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<\/code><\/pre>\n<p>\n\u010ce current postane enak null, pomeni, da je iskanje doseglo konec drevesa (na konceptualni ravni ste v neobstoje\u010dem delu drevesa \u2014 potomcu lista).<\/p>\n<p>Poglejmo u\u010dinkovitost iskalnega algoritma na uravnote\u017eenem drevesu (drevesu, kjer so vozli\u0161\u010da razporejena bolj ali manj enakomerno). Takrat bo u\u010dinkovitost iskanja O(log(n)), pri \u010demer je logaritem pri osnovi 2. Poglejte: \u010de ima v uravnote\u017eenem drevesu n elementov, to pomeni, da bo log(n) pri osnovi 2 nivojev drevesa. Med iskanjem, v enem koraku zanke, se spustite za en nivo.<\/p>\n<h3>Vstavljanje<\/h3>\n<p>\n\u010ce ste ujeli bistvo iskanja, vam vstavljanje ne bo predstavljalo te\u017eav. Preprosto se morate spustiti do lista drevesa (po pravilih spu\u0161\u010danja, opisanih v iskanju) in postati njegov potom\u010dek - levi ali desni, odvisno od klju\u010da. Izvedba:<\/p>\n<pre><code class=\"java\">   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<\/code><\/pre>\n<p>\nV tem primeru je poleg trenutnega vozli\u0161\u010da potrebno shraniti tudi informacije o star\u0161u trenutnega vozli\u0161\u010da. Ko current postane enak null, bo v spremenljivki parent le\u017eala potrebna igralna plo\u0161\u010da. <br \/>\nU\u010dinkovitost vstavljanja bo o\u010ditno enaka kot pri iskanju - O(log(n)).<\/p>\n<h3>Odstranjevanje<\/h3>\n<p>\nIzbris je najte\u017eja operacija, ki jo je treba izvesti z drevesom. Jasno je, da je najprej treba najti element, ki ga nameravamo izbrisati. Ampak kaj potem? \u010ce preprosto dodelimo njegovemu kazalcu vrednost null, bomo izgubili informacije o poddrevesu, katerega koren je to vozli\u0161\u010de. Metode za brisanje drevesa delimo na tri primere.<\/p>\n<h4>Prvi primer. Izbrisano vozli\u0161\u010de nima potomcev.<\/h4>\n<p>\n\u010ce izbrisano vozli\u0161\u010de nima potomcev, to pomeni, da je list. Zato lahko poljem leftChild ali rightChild njegovega star\u0161a preprosto dodelimo vrednost null. <\/p>\n<h4>Drugi primer. Izbrisano vozli\u0161\u010de ima enega potomca.<\/h4>\n<p>\nTa primer tudi ni zelo zapleten. Vrnimo se k na\u0161emu primeru. Recimo, da je potrebno izbrisati element s klju\u010dem 14. Strinjate se, da ker je to desni potomec vozli\u0161\u010da s klju\u010dem 10, bo vsak njegov potomec (v tem primeru desni) imel klju\u010d, ve\u010dji od 10, zato ga lahko zlahka \"izre\u017eemo\" iz drevesa, star\u0161a pa pove\u017eemo neposredno s potomcem izbrisanega vozli\u0161\u010da, torej vozli\u0161\u010de s klju\u010dem 10 pove\u017eemo z vozli\u0161\u010dem 13. Podobna situacija bi bila, \u010de bi morali izbrisati vozli\u0161\u010de, ki je levi potomec svojega star\u0161a. Razmislite o tem sami - to\u010dna analogija. <\/p>\n<h4>Tretji primer. Vozli\u0161\u010de ima dva potomca.<\/h4>\n<p>\nNajbolj zapleten primer. Razdelimo na novem primeru.<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree ali kako pripraviti binarno iskalno drevo\" src=\"\/wp-content\/uploads\/2019\/03\/0d600478e4a046ae6f7267be49b231bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>Iskanje naslednika<\/h4>\n<p>\n Recimo, da je potrebno odstraniti vozli\u0161\u010de s klju\u010dno \u0161tevilko 25. Koga bomo postavili na njegovo mesto? Nekdo iz njegovih naslednikov (potomcev ali potomcev potomcev) mora postati <i>naslednik<\/i>(tisti, ki bo zasedel mesto odstranjene vozli\u0161\u010da). <\/p>\n<p>Kako razumeti, kdo bi moral postati naslednik? Intuitivno razumemo, da je to vozli\u0161\u010de v drevesu, katerega klju\u010d je naslednji najve\u010dji od odstranjene vozli\u0161\u010da. Algoritem je naslednji. Premakniti se je treba k njegovemu desnemu potomcu (vedno k desnemu, saj je \u017ee bilo omenjeno, da je klju\u010d naslednika ve\u010dji od klju\u010da odstranjene vozli\u0161\u010da), nato pa prehoditi verigo levih potomcev tega desnega potomca. V na\u0161em primeru se moramo preseliti k vozli\u0161\u010du s klju\u010dno \u0161tevilko 35 in nato prehoditi do lista navzdol po verigi njegovih levih potomcev \u2013 v tem primeru ta veriga vsebuje le vozli\u0161\u010de s klju\u010dno \u0161tevilko 30. Strogo gledano, i\u0161\u010demo najmanj\u0161e vozli\u0161\u010de v sku\u0161ini vozli\u0161\u010d, ki so ve\u010dja od iskane vozli\u0161\u010da.<\/p>\n<p><img decoding=\"async\" alt=\"Binary Tree ali kako pripraviti binarno iskalno drevo\" src=\"\/wp-content\/uploads\/2019\/03\/50c4e3e49111eec9e1fd13083ee9b9b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKoda metode iskanja naslednika:<\/p>\n<pre><code class=\"java\">    public Node getSuccessor(Node deleteNode) {\n        Node parentSuccessor = deleteNode; \/\/ star\u0161 naslednika\n        Node successor = deleteNode; \/\/ naslednik\n        Node current = successor.getRightChild(); \/\/ preprosto 'prehajajo\u010de' vozli\u0161\u010de\n        while (current != null) {\n            parentSuccessor = successor;\n            successor = current;\n            current = current.getLeftChild();\n        }\n        \/\/ ob izhodu iz cikla imamo naslednika in star\u0161a naslednika\n        if (successor != deleteNode.getRightChild()) { \/\/ \u010de se naslednik ne ujema s desnim potomcem odstranjene vozli\u0161\u010da\n            parentSuccessor.setLeftChild(successor.getRightChild()); \/\/ njegov star\u0161 prevzame potomca naslednika, da ga ne izgubi\n            successor.setRightChild(deleteNode.getRightChild()); \/\/ pove\u017eemo naslednika z desnim potomcem odstranjene vozli\u0161\u010da\n        }\n        return successor;\n    }\n<\/code><\/pre>\n<p>\nPolna koda metode delete:<\/p>\n<pre><code class=\"java\">public boolean delete(int deleteKey) {\n        Node current = root;\n        Node parent = current;\n        boolean isLeftChild = false; \/\/Depending on whether the node to be deleted is a left or right child of its parent, the boolean variable isLeftChild will be true or false accordingly.\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) { \/\/first case\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) { \/\/second case\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 { \/\/third case\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>\nThe complexity can be approximated to O(log(n)).<\/p>\n<h3>Finding the maximum\/minimum in a tree<\/h3>\n<p>\nObviously, to find the minimum\/maximum value in the tree, you need to sequentially traverse the chain of left\/right tree elements respectively; when you reach a leaf, it will be the minimum\/maximum 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>\nThe complexity is O(log(n))<\/p>\n<h3>Symmetric traversal<\/h3>\n<p>\nTraversal means visiting each node of the tree to perform some action on it.<\/p>\n<p>The algorithm for recursive symmetric traversal:<\/p>\n<ol>\n<li>Perform an action with the left child<\/li>\n<li>Perform an action with itself<\/li>\n<li>Perform an action with the right child<\/li>\n<\/ol>\n<p>\nKoda:<\/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() + \" \");\/\/Tu lahko pride vse mogo\u010de\n            inOrder(current.getRightChild());\n        }\n    }\n<\/code><\/pre>\n<p><\/p>\n<h2>Zaklju\u010dek<\/h2>\n<p>\nKon\u010dno! \u010ce mam kaj nedore\u010denega ali imate kak\u0161ne pripombe, jih pri\u010dakujem v komentarjih. Kot sem obljubil, prina\u0161am celoten kodo.<\/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\">javna klasa BinaryTree&lt;T&gt; {\n    privatna Node&lt;T&gt; root;\n\n    javni Node&lt;T&gt; find(int key) {\n        Node&lt;T&gt; current = root;\n        dok (current.getKey() != key) {\n            ako (key &lt; current.getKey())\n                current = current.getLeftChild();\n            ina\u010de\n                current = current.getRightChild();\n            ako (current == null)\n                vrati null;\n        }\n        vrati current;\n    }\n\n    javna 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        ako (root == null)\n            root = newNode;\n        ina\u010de {\n            dok (true) {\n                parent = current;\n                ako (key &lt; current.getKey()) {\n                    current = current.getLeftChild();\n                    ako (current == null) {\n                         parent.setLeftChild(newNode);\n                         vrati;\n                    }\n                }\n                ina\u010de {\n                    current = current.getRightChild();\n                    ako (current == null) {\n                        parent.setRightChild(newNode);\n                        vrati;\n                    }\n                }\n            }\n        }\n    }\n\n    javni 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        dok (current != null) {\n            parent = current;\n            current = current.getLeftChild();\n        }\n        vrati parent;\n    }\n\n    javni 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        dok (current != null) {\n            parent = current;\n            current = current.getRightChild();\n        }\n        vrati parent;\n    }\n\n    javni 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        dok (current != null) {\n            parentSuccessor = successor;\n            successor = current;\n            current = current.getLeftChild();\n        }\n\n        ako (successor != deleteNode.getRightChild()) {\n            parentSuccessor.setLeftChild(successor.getRightChild());\n            successor.setRightChild(deleteNode.getRightChild());\n        }\n        vrati successor;\n    }\n\n    javni boolean delete(int deleteKey) {\n        Node&lt;T&gt; current = root;\n        Node&lt;T&gt; parent = current;\n        boolean isLeftChild = false;\n        dok (current.getKey() != deleteKey) {\n            parent = current;\n            ako (deleteKey &lt; current.getKey()) {\n                current = current.getLeftChild();\n                isLeftChild = true;\n            } else {\n                isLeftChild = false;\n                current = current.getRightChild();\n            }\n            ako (current == null)\n                vrati false;\n        }\n\n        ako (current.getLeftChild() == null &amp;&amp; current.getRightChild() == null) {\n            ako (current == root)\n                current = null;\n            ina\u010de ako (isLeftChild)\n                parent.setLeftChild(null);\n            ina\u010de\n                parent.setRightChild(null);\n        }\n        ina\u010de ako (current.getRightChild() == null) {\n            ako (current == root)\n                root = current.getLeftChild();\n            ina\u010de ako (isLeftChild)\n                parent.setLeftChild(current.getLeftChild());\n            ina\u010de\n                current.setRightChild(current.getLeftChild());\n        } ina\u010de ako (current.getLeftChild() == null) {\n            ako (current == root)\n                root = current.getRightChild();\n            ina\u010de ako (isLeftChild)\n                parent.setLeftChild(current.getRightChild());\n            ina\u010de\n                parent.setRightChild(current.getRightChild());\n        } \n        ina\u010de {\n            Node&lt;T&gt; successor = getSuccessor(current);\n            ako (current == root)\n                root = successor;\n            ina\u010de ako (isLeftChild)\n                parent.setLeftChild(successor);\n            ina\u010de\n                parent.setRightChild(successor);\n        }\n        vrati true;\n    }\n\n    javna void inOrder(Node&lt;T&gt; current) {\n        ako (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>Za\u010detenje do O(n)<\/h3>\n<p>\nMnogi od vas su mogli primetiti: a \u0161ta ako u\u010dinite da drvo postane neusagla\u0161eno? Na primer, umetnite \u010dvorove sa rastu\u0107im klju\u010devima: 1,2,3,4,5,6\u2026 Tada \u0107e drvo vi\u0161e li\u010diti na povezanu listu. I da, drvo \u0107e izgubiti svoju hijerarhijsku strukturu, a samim tim i efikasnost pristupa podacima. Slo\u017eenost operacija pretrage, umetanja, brisanja posta\u0107e kao kod povezane liste: O(n). U tome se otkriva jedan od najva\u017enijih, po mom mi\u0161ljenju, nedostataka binarnih stabala.<\/p>\n<p class=\"for_users_only_msg\">Samo registrovani korisnici mogu u\u010destvovati u anketi. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Prijavite se<\/a><\/noindex>, molim vas.<\/p>\n<h2 class=\"default-block__polling-title\">Nisam dugo na habru, i voleo bih da znam koje teme biste \u017eeleli da vidite vi\u0161e?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Podatkovne strukture<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Algoritmi (DP, rekurzija, kompresija podataka itd.)<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Primena podatkovnih struktura i algoritama u stvarnom \u017eivotu<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programiranje android aplikacija na Javi<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programiranje web aplikacija na Javi<\/p>\n<\/li>\n<\/ul>\n<p>    2 pengguna memberikan suara. 1 pengguna memilih tidak memihak.<br \/>\n<br \/>Izvor: 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.4 - 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\/sl\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\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\/sl\/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 ili kako pripremiti binarno stablo pretrage | ProHoster","description":"Preludij Ovaj \u010dlanak je posve\u0107en binarnim stablima pretrage.","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","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\/sl\/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\/sl\/wp-json\/wp\/v2\/posts\/30530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=30530"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/30530\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/22528"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=30530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=30530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=30530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}