{"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\/no\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","title":{"rendered":"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<h2>Forord<\/h2>\n<p>\nDenne artikkelen handler om bin\u00e6re s\u00f8ketre. Jeg skrev nylig en artikkel om <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/438512\/\">data komprimering ved hjelp av Huffman-metoden.<\/a><\/noindex> Der fokuserte jeg ikke mye p\u00e5 bin\u00e6re tr\u00e6r, siden metoder for s\u00f8k, innsetting og sletting ikke var aktuelle. N\u00e5 har jeg bestemt meg for \u00e5 skrive en artikkel spesifikt om tr\u00e6r. La oss begynne. <\/p>\n<p>Et tre er en datstruktur best\u00e5ende av noder koblet sammen med kanter. Man kan si at et tre er et spesialtilfelle av en graf. Her er et eksempel p\u00e5 et tre: <\/p>\n<p><img decoding=\"async\" alt=\"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre\" src=\"\/wp-content\/uploads\/2019\/03\/502ac27f1b93f926c68a68777f6bddd7.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDette er ikke et bin\u00e6rt s\u00f8ketre! Alt under kat!<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Terminologi<\/h2>\n<p><\/p>\n<h4>Rot<\/h4>\n<p>\n<i>Roten av treet<\/i> er den \u00f8verste noden. I eksemplet er dette node A. I treet kan det kun finnes \u00e9n vei fra roten til hvilken som helst annen node! Egentlig kan enhver node betraktes som roten til det tilsvarende deltreet.<\/p>\n<h4>Foreldre \/ etterkommere<\/h4>\n<p>\nAlle noder, bortsett fra roten, har n\u00f8yaktig \u00e9n kant som g\u00e5r opp til en annen node. En node som ligger over den n\u00e5v\u00e6rende noden, kalles <i>forelderen<\/i> til denne noden. En node som ligger under den n\u00e5v\u00e6rende noden og er koblet til den, kalles <i>etterkommeren<\/i> til denne noden. La oss ta et eksempel. Ta node B, da vil forelderen v\u00e6re node A, og etterkommerne vil v\u00e6re nodene D, E og F.<\/p>\n<h4>Blad<\/h4>\n<p>\nEn node som ikke har noen etterkommere, kalles et blad i treet. I eksemplet vil bladene v\u00e6re nodene D, E, F, G, I, J, K.<\/p>\n<p>Dette er hovedterminologien. Andre begreper vil bli diskutert senere. S\u00e5 et bin\u00e6rt tre er et tre der hver node har ikke mer enn to etterkommere. Som dere kanskje har gjettet, vil treet fra eksemplet ikke v\u00e6re bin\u00e6rt, fordi nodene B og H har mer enn to etterkommere. Her er et eksempel p\u00e5 et bin\u00e6rt tre:<\/p>\n<p><img decoding=\"async\" alt=\"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre\" src=\"\/wp-content\/uploads\/2019\/03\/2f587bd1c428d3850cb0163d6c2984a1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNodene i treet kan inneholde hvilken som helst informasjon. Et bin\u00e6rt s\u00f8ketre er et bin\u00e6rt tre som er preget av f\u00f8lgende egenskaper:<\/p>\n<ol>\n<li>Begge deltreene \u2014 venstre og h\u00f8yre \u2014 er bin\u00e6re s\u00f8ketre.<\/li>\n<li>Alle noder i venstre deltre av en tilfeldig node X har datan\u00f8kkelverdier som er mindre enn n\u00f8kkelverdien til node X.<\/li>\n<li>Alle noder i h\u00f8yre deltre av en tilfeldig node X har datan\u00f8kkelverdier som er st\u00f8rre enn eller lik n\u00f8kkelverdien til node X. <\/li>\n<\/ol>\n<p><i>N\u00f8kkel<\/i> \u2014 en egenskap ved noden (for eksempel et tall). N\u00f8kkelen er n\u00f8dvendig for \u00e5 finne elementet i treet som tilsvarer denne n\u00f8kkelen. Eksempel p\u00e5 et bin\u00e6rt s\u00f8ketre:<\/p>\n<p><img decoding=\"async\" alt=\"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre\" src=\"\/wp-content\/uploads\/2019\/03\/a70ca7d2fdf289b5d1e14bdb4bc38b00.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h2>Presentasjon av treet<\/h2>\n<p>\nEtter hvert som jeg g\u00e5r gjennom, vil jeg gi noen (kanskje ufullstendige) kodebiter for \u00e5 forbedre forst\u00e5elsen din. Fullstendig kode vil v\u00e6re p\u00e5 slutten av artikkelen. <\/p>\n<p>Treet best\u00e5r av noder. Strukturen til en node:<\/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\/\/...andre metoder for noden\n}\n<\/code><\/pre>\n<p>\nHver node har to etterkommere (det kan godt v\u00e6re at etterkommerne leftChild og\/eller rightChild inneholder null). Du har sikkert f\u00e5tt med deg at i dette tilfellet er data \u2014 dataene som lagres i noden; key \u2014 n\u00f8kkelen til noden.<\/p>\n<p>N\u00e5 som vi har forst\u00e5tt noden, la oss snakke om aktuelle problemer med tr\u00e6r. Her og videre vil jeg med ordet \"tre\" mene konseptet av et bin\u00e6rt s\u00f8ketre. Strukturen til et bin\u00e6rt tre:<\/p>\n<pre><code class=\"java\">public class BinaryTree&lt;T&gt; {\n     private Node&lt;T&gt; root;\n\n    \/\/metoder for treet\n}\n<\/code><\/pre>\n<p>Som et klassefelt trenger vi bare roten av treet, ettersom vi kan n\u00e5 hvilken som helst node i treet fra roten ved hjelp av metodene getLeftChild() og getRightChild().<\/p>\n<h2>Algoritmer i treet<\/h2>\n<p><\/p>\n<h3>S\u00f8k<\/h3>\n<p>\nLa oss si at du har et konstruert tre. Hvordan finner man elementet med n\u00f8kkelen key? Du m\u00e5 bevege deg fra roten nedover i treet og sammenligne verdien av key med n\u00f8kkelen til den n\u00e5v\u00e6rende noden: hvis key er mindre enn n\u00f8kkelen til den n\u00e5v\u00e6rende noden, g\u00e5 til venstre etterkommer av noden, hvis det er st\u00f8rre \u2014 til h\u00f8yre, hvis n\u00f8klene er like \u2014 s\u00e5 er den \u00f8nskede noden funnet! Den tilsvarende koden:<\/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>\nHvis current blir lik null, betyr det at vi har n\u00e5dd slutten av treet (p\u00e5 et konseptuelt niv\u00e5 befinner du deg p\u00e5 et ikke-eksisterende sted i treet \u2014 en etterkommer av et blad).<\/p>\n<p>Vi vurderer effektiviteten av s\u00f8kealgoritmen p\u00e5 et balansert tre (et tre der nodene er mer eller mindre jevnt fordelt). Da vil effektiviteten av s\u00f8ket v\u00e6re O(log(n)), der logaritmen er med base 2. Se: hvis det er n elementer i det balanserte treet, betyr det at treet vil ha log(n) niv\u00e5er med base 2. I s\u00f8ket, for hvert steg i l\u00f8kken, g\u00e5r du ned ett niv\u00e5.<\/p>\n<h3>Innf\u00f8ring<\/h3>\n<p>\nDersom du har fanget essensen av s\u00f8ket, vil det v\u00e6re enkelt \u00e5 forst\u00e5 innsettingen. Du m\u00e5 bare g\u00e5 ned til bladet i treet (i henhold til nedstigningsreglene beskrevet i s\u00f8ket) og bli dets etterkommere \u2014 venstre eller h\u00f8yre, avhengig av n\u00f8kkelen. Implementering:<\/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>\nI dette tilfellet m\u00e5 vi, i tillegg til den gjeldende noden, lagre informasjon om forelderen til den gjeldende noden. N\u00e5r current blir lik null, vil variabelen parent inneholde det bladet vi trenger. <br \/>\nEffektiviteten av innsetting vil \u00e5penbart v\u00e6re den samme som for s\u00f8ket \u2014 O(log(n)).<\/p>\n<h3>Sletting<\/h3>\n<p>\nSletting er den vanskeligste operasjonen vi m\u00e5 utf\u00f8re med treet. Det er klart at vi f\u00f8rst m\u00e5 finne elementet som vi \u00f8nsker \u00e5 slette. Men hva s\u00e5? Hvis vi bare setter referansen til null, vil vi miste informasjon om undertr\u00e6rne, hvis rot er denne noden. Metoder for sletting av treet deles inn i tre tilfeller.<\/p>\n<h4>F\u00f8rste tilfelle. Den slettede noden har ingen etterkommere.<\/h4>\n<p>\nHvis den slettede noden ikke har noen etterkommere, betyr det at den er et blad. F\u00f8lgelig kan vi bare sette feltene leftChild eller rightChild til forelderen hans til null. <\/p>\n<h4>Andre tilfelle. Den slettede noden har \u00e9n etterkommer.<\/h4>\n<p>\nDette tilfellet er heller ikke veldig komplisert. La oss g\u00e5 tilbake til v\u00e5rt eksempel. La oss si at vi m\u00e5 slette elementet med n\u00f8kkel 14. S\u00e5 lenge det er en h\u00f8yre etterkommer av noden med n\u00f8kkel 10, vil enhver av dens etterkommere (i dette tilfellet h\u00f8yre) ha en n\u00f8kkel som er st\u00f8rre enn 10, s\u00e5 vi kan enkelt \"kutte\" det ut av treet, og koble forelderen direkte til etterkommeren til den slettede noden, dvs. koble noden med n\u00f8kkel 10 direkte til noden 13. En lignende situasjon ville v\u00e6re hvis vi m\u00e5tte slette en node som er venstre etterkommer av forelderen sin. Tenk p\u00e5 det selv \u2014 en n\u00f8yaktig analogi. <\/p>\n<h4>Tredje tilfelle. Noden har to etterkommere.<\/h4>\n<p>\nDet mest komplekse tilfellet. La oss analysere det med et nytt eksempel.<\/p>\n<p><img decoding=\"async\" alt=\"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre\" src=\"\/wp-content\/uploads\/2019\/03\/0d600478e4a046ae6f7267be49b231bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>S\u00f8ke etter etterf\u00f8lger<\/h4>\n<p>\n La oss si vi m\u00e5 fjerne noden med n\u00f8kkelen 25. Hvem skal vi sette i stedet for den? Noen av etterkommerne (eller etterkommernes etterkommere) m\u00e5 bli <i>arvingen<\/i>(den som vil ta plassen til den fjernede noden). <\/p>\n<p>Hvordan forst\u00e5r vi hvem som skal bli arvingen? Det er intuitivt klart at det er noden i treet hvis n\u00f8kkel er den neste st\u00f8rrelsen st\u00f8rre enn den fjernede noden. Algoritmen g\u00e5r som f\u00f8lger. Vi m\u00e5 g\u00e5 til h\u00f8yre etterkommer (alltid til h\u00f8yre, for det har allerede blitt sagt at arvingen har en st\u00f8rre n\u00f8kkel enn den fjernede noden), og deretter f\u00f8lge kjeden av venstre etterkommere til denne h\u00f8yre etterkommeren. I eksemplet m\u00e5 vi g\u00e5 til noden med n\u00f8kkel 35, og deretter f\u00f8lge kjeden nedover til bladet av venstre etterkommere \u2014 i dette tilfellet best\u00e5r denne kjeden bare av noden med n\u00f8kkel 30. Strengt tatt leter vi etter den minste noden i settet av noder som er st\u00f8rre enn den s\u00f8kte noden.<\/p>\n<p><img decoding=\"async\" alt=\"Binar Tre eller hvordan lage et bin\u00e6rt s\u00f8ketre\" src=\"\/wp-content\/uploads\/2019\/03\/50c4e3e49111eec9e1fd13083ee9b9b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKode for metoden for \u00e5 finne arvingen:<\/p>\n<pre><code class=\"java\">    public Node getSuccessor(Node deleteNode) {\n        Node parentSuccessor = deleteNode; \/\/ forelder av arvingen\n        Node successor = deleteNode; \/\/ arvingen\n        Node current = successor.getRightChild(); \/\/ bare \"gjennoml\u00f8pende\" node\n        while (current != null) {\n            parentSuccessor = successor;\n            successor = current;\n            current = current.getLeftChild();\n        }\n        \/\/ N\u00e5r vi forlater l\u00f8kken har vi arvingen og forelderen til arvingen\n        if (successor != deleteNode.getRightChild()) { \/\/ hvis arvingen ikke er den samme som h\u00f8yre etterkommer av den fjernede noden\n            parentSuccessor.setLeftChild(successor.getRightChild()); \/\/ s\u00e5 tar forelderen den etterkommeren av arvingen, s\u00e5 den ikke g\u00e5r tapt\n            successor.setRightChild(deleteNode.getRightChild()); \/\/ kobler arvingen til h\u00f8yre etterkommer av den fjernede noden\n        }\n        return successor;\n    }\n<\/code><\/pre>\n<p>\nDen komplette koden for metoden delete:<\/p>\n<pre><code class=\"java\">public boolean delete(int deleteKey) {\n        Node current = root;\n        Node parent = current;\n        boolean isLeftChild = false; \/\/ Avhengig av om den slettede noden er et venstre eller h\u00f8yre barn av forelderen, vil boolsk variabel isLeftChild v\u00e6re true eller 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) { \/\/ f\u00f8rste tilfelle\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) { \/\/ andre tilfelle\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 { \/\/ tredje tilfelle\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>\nKompleksiteten kan tiln\u00e6rmes til O(log(n)).<\/p>\n<h3>Finne maksimum\/minimum i treet<\/h3>\n<p>\nDet er \u00e5penbart hvordan man finner minimum\/maksimum verdien i treet - man m\u00e5 f\u00f8lge kjeden av venstre\/h\u00f8yre elementer i treet henholdsvis; n\u00e5r man kommer til et blad, vil det v\u00e6re minimum\/maksimum elementet.<\/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>\nKompleksitet - O(log(n))<\/p>\n<h3>Symmetrisk traversering<\/h3>\n<p>\nTraversering - bes\u00f8ke hver node i treet for \u00e5 gj\u00f8re noe med den.<\/p>\n<p>Algoritmen for rekursiv symmetrisk traversering:<\/p>\n<ol>\n<li>Gj\u00f8re noe med venstre barn<\/li>\n<li>Gj\u00f8re noe med seg selv<\/li>\n<li>Gj\u00f8re noe med h\u00f8yre barn<\/li>\n<\/ol>\n<p>\nKode:<\/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() + \" \"); \/\/Her kan det v\u00e6re alt mulig\n            inOrder(current.getRightChild());\n        }\n    }\n<\/code><\/pre>\n<p><\/p>\n<h2>Konklusjon<\/h2>\n<p>\nEndelig! Hvis jeg har utelatt noe eller hvis det er noen merknader, ser jeg frem til kommentarene. Som lovet, her er fullstendig kode.<\/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>Degenerering til O(n)<\/h3>\n<p>\nMange av dere kan ha lagt merke til: hva om vi gj\u00f8r treet ubalansert? For eksempel, legge inn noder med \u00f8kende n\u00f8kler: 1, 2, 3, 4, 5, 6\u2026 Da vil treet minne om en lenket liste. Og ja, treet vil miste sin trefasete struktur, og dermed effektiviteten ved datatilgang. Komplekset av s\u00f8ke-, sette inn og slette operasjoner vil bli som for en lenket liste: O(n). Dette er en av de viktigste, etter min mening, ulempene ved bin\u00e6re tr\u00e6r.<\/p>\n<p class=\"for_users_only_msg\">Kun registrerte brukere kan delta i unders\u00f8kelsen. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Logg inn<\/a><\/noindex>, v\u00e6r s\u00e5 snill.<\/p>\n<h2 class=\"default-block__polling-title\">Jeg har ikke v\u00e6rt p\u00e5 Habr lenge, og jeg lurer p\u00e5 hvilke emner dere \u00f8nsker \u00e5 se flere artikler om?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Datastrukturer<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Algoritmer (DP, rekursjon, datakomprimering osv.)<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Bruk av datastrukturer og algoritmer i det virkelige liv<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programmering av Android-applikasjoner p\u00e5 Java<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Programmering av webapplikasjoner p\u00e5 Java<\/p>\n<\/li>\n<\/ul>\n<p>    2 brukere har stemt. 1 bruker avholdt seg.<br \/>\n<br \/>Kilde: 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.5 - 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\/no\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.5\" \/>\n\t\t<meta property=\"og:locale\" content=\"nn_NO\" \/>\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\/no\/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 eller hvordan lage et bin\u00e6rt s\u00f8ketr\u00e6r | ProHoster","description":"Prelude Denne artikkelen er viet til bin\u00e6re s\u00f8ketr\u00e6r.","canonical_url":"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/binary-tree-ili-kak-prigotovit-binarnoe-derevo-poiska","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nn_NO","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\/no\/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\/no\/wp-json\/wp\/v2\/posts\/30530","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/comments?post=30530"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts\/30530\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/media\/22528"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/media?parent=30530"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/categories?post=30530"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/tags?post=30530"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}