Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Kuwonetseratu

Nkhaniyi ikunena za mitengo yosaka bayinare. Posachedwapa ndachita nkhani yokhudza Kuphatikizika kwa data pogwiritsa ntchito njira ya Huffman. Kumeneko sindinasamalire kwambiri mitengo ya binary, chifukwa kufufuza, kuyika, ndi kuchotsa njira sizinali zoyenera. Tsopano ndinaganiza zolemba nkhani yokhudza mitengo. Tiyeni tiyambe.

Mtengo ndi dongosolo la data lomwe lili ndi mfundo zolumikizidwa ndi m'mphepete. Tikhoza kunena kuti mtengo ndi nkhani yapadera ya graph. Nachi chitsanzo cha mtengo:

Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Uwu si mtengo wosaka wa binary! Zonse zadulidwa!

Mawu omaliza

Muzu

Muzu wamtengo - iyi ndiye mfundo yake yapamwamba kwambiri. Mu chitsanzo, iyi ndi mfundo A. Mumtengo, njira imodzi yokha ingatsogolere kuchokera ku muzu kupita ku mfundo ina iliyonse! M'malo mwake, node iliyonse imatha kuonedwa ngati muzu wa subtree yolingana ndi mfundo iyi.

Makolo/mbadwa

Manode onse kupatula muzu ali ndi m'mphepete mwake womwe umatsogolera ku mfundo ina. Node yomwe ili pamwamba pakali pano imatchedwa kholo node izi. Node yomwe ili pansipa yomwe ilipo ndipo yolumikizidwa nayo imatchedwa wobadwa node izi. Tiyeni tigwiritse ntchito chitsanzo. Tiyeni titenge mfundo B, ndiye kholo lake lidzakhala node A, ndipo ana ake adzakhala mfundo D, E ndi F.

Leaf

Node yomwe ilibe ana idzatchedwa tsamba la mtengo. Mu chitsanzo, masamba adzakhala mfundo D, E, F, G, I, J, K.

Awa ndi mawu oyambira. Mfundo zina zidzakambidwanso. Choncho, mtengo wa binary ndi mtengo umene node iliyonse idzakhala ndi ana osapitirira awiri. Monga momwe mumaganizira, mtengo wochokera ku chitsanzo sudzakhala wa binary, chifukwa nodes B ndi H ali ndi ana oposa awiri. Nachi chitsanzo cha mtengo wa binary:

Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Mitengo yamitengo imatha kukhala ndi chidziwitso chilichonse. Mtengo wosakira wa binary ndi mtengo wa binary womwe uli ndi zotsatirazi:

  1. Mitengo yaing'ono kumanzere ndi kumanja ndi mitengo yosakira.
  2. Ma node onse akumanzere kwa node yokhazikika X ali ndi makiyi achinsinsi kuposa mtengo wa kiyi ya data ya X yokha.
  3. Ma node onse omwe ali m'munsi kumanja kwa node yokhazikika X ali ndi makiyi a data kuposa kapena ofanana ndi mtengo wa kiyi ya data ya X yokha.

Mphindi - chikhalidwe chilichonse cha node (mwachitsanzo, nambala). Chinsinsi ndichofunika kuti mupeze chinthu chamtengo chomwe funguloli likugwirizana nalo. Chitsanzo cha mtengo wofufuzira wa binary:

Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Mawonedwe amitengo

Pamene tikupita patsogolo, ndikupatsani ma code (mwina osakwanira) kuti mumvetsetse bwino. Khodi yonse idzakhala kumapeto kwa nkhaniyo.

Mtengo umakhala ndi mfundo. Mapangidwe a Node:

public class Node<T> {
    private T data;
    private int key;
    private Node<T> leftChild;
    private Node<T> rightChild;

    public Node(T data, int key) {
        this.data = data;
        this.key = key;
    }
    public Node<T> getLeftChild() {
        return leftChild;
    }

    public Node<T> getRightChild() {
        return rightChild;
    }
//...ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΡƒΠ·Π»Π°
}

Node iliyonse ili ndi ana awiri (ndizotheka kuti ana a leftChild ndi/kapena rightChild akhale ndi mtengo wopanda pake). Mwinamwake mwazindikira kuti mu nkhaniyi chiwerengero cha deta ndi deta yosungidwa mu node; key - key node.

Takonza mfundoyi, tsopano tiyeni tikambirane za zovuta zamitengo. Pambuyo pake, ndi mawu oti "mtengo" ndikutanthauza lingaliro la mtengo wosaka wa binary. Kapangidwe ka mtengo wa binary:

public class BinaryTree<T> {
     private Node<T> root;

    //ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Π΄Π΅Ρ€Π΅Π²Π°
}

Timangofunikira muzu wa mtengowo ngati gawo la kalasi, chifukwa kuchokera muzu, pogwiritsa ntchito njira za getLeftChild () ndi getRightChild (), mukhoza kufika ku mfundo iliyonse mumtengo.

Ma algorithms mumtengo

Поиск

Tiyerekeze kuti muli ndi mtengo womangidwa. Mungapeze bwanji chinthu chokhala ndi kiyi ya kiyi? Muyenera kusuntha motsatizana kuchokera muzu pansi pamtengo ndikufanizira mtengo wa kiyi ndi fungulo la node yotsatira: ngati fungulo liri locheperapo fungulo la node yotsatira, ndiye kupita kumanzere kwa node, ngati ili. chachikulu, kumanja, ngati makiyi ali ofanana, mfundo yofunidwa imapezeka! Kodi yoyenera:

public Node<T> find(int key) {
    Node<T> current = root;
    while (current.getKey() != key) {
        if (key < current.getKey())
            current = current.getLeftChild();
        else
            current = current.getRightChild();
        if (current == null)
            return null;
    }
    return current;
}

Ngati zamakono zakhala zopanda ntchito, ndiye kuti kufufuza kwafika kumapeto kwa mtengo (pamalingaliro, muli pamalo omwe mulibe mumtengo - mbadwa ya tsamba).

Tiyeni tiwone momwe ntchito yofufuzira ilili pamtengo wokhazikika (mtengo womwe node amagawika mochulukirapo kapena mochepera). Ndiye kufufuza bwino kudzakhala O(log(n)), ndipo logarithm ndi base 2. Yang'anani: ngati pali n element mumtengo wokwanira, ndiye izi zikutanthauza kuti padzakhala chipika(n) ku maziko a 2 mtengo. Ndipo pofufuza, mu sitepe imodzi ya kuzungulira, mumatsika mulingo umodzi.

kumanga

Ngati mumvetsetsa tanthauzo lakusaka, ndiye kuti kumvetsetsa kuyikako sikudzakhala kovuta kwa inu. Mukungoyenera kupita kutsamba la mtengo (malinga ndi malamulo otsetsereka omwe akufotokozedwa pakufufuza) ndikukhala mbadwa yake - kumanzere kapena kumanja, kutengera fungulo. Kukhazikitsa:

   public void insert(T insertData, int key) {
        Node<T> current = root;
        Node<T> parent;
        Node<T> newNode = new Node<>(insertData, key);
        if (root == null)
            root = newNode;
        else {
            while (true) {
                parent = current;
                if (key < current.getKey()) {
                    current = current.getLeftChild();
                    if (current == null) {
                         parent.setLeftChild(newNode);
                         return;
                    }
                }
                else {
                    current = current.getRightChild();
                    if (current == null) {
                        parent.setRightChild(newNode);
                        return;
                    }
                }
            }
        }
    }

Pankhaniyi, kuwonjezera pa node yamakono, m'pofunika kusunga zambiri za kholo la node yamakono. Zatsopano zikakhala zofanana ndi zopanda pake, kusintha kwa makolo kumakhala ndi pepala lomwe tikufuna.
Kuchita bwino kwa kuyikako kudzakhala kofanana ndi kufufuzidwa - O(logi(n)).

Chotsani

Kuchotsa ndi ntchito yovuta kwambiri yomwe idzafunika kuchitidwa pamtengo. Zikuwonekeratu kuti choyamba tifunika kupeza chinthu chomwe tikufuna kuchotsa. Koma ndiye chiyani? Ngati tingoyika zolemba zake za null, tidzataya chidziwitso cha subtree yomwe node iyi ndi muzu. Njira zochotsera mitengo zimagawidwa m'magawo atatu.

Nkhani yoyamba. Node yomwe ikuchotsedwa ilibe ana

Ngati mfundo ikuchotsedwa ilibe ana, ndiye kuti ndi tsamba. Chifukwa chake, mutha kungoyika magawo a leftChild kapena RightChild a kholo lake kuti asakhalenso.

Mlandu wachiwiri. Node yoti achotsedwe ali ndi mwana mmodzi

Mlanduwu nawonso siwovuta kwambiri. Tiyeni tibwerere ku chitsanzo chathu. Tinene kuti tikufunika kuchotsa chinthu chokhala ndi kiyi 14. Vomerezani kuti popeza ndi mbadwa yoyenera ya nodi yokhala ndi kiyi 10, ndiye kuti mbadwa zake zilizonse (pankhaniyi yoyenera) zidzakhala ndi kiyi yayikulu kuposa 10, kotero inu mosavuta "kudula" mu mtengo, ndi kulumikiza kholo mwachindunji kwa mwana mfundo zikuchotsedwa, i.e. gwirizanitsani mfundo ndi kiyi 10 ku mfundo 13. Zinthu zikanakhala zofanana ngati kukanakhala koyenera kuchotsa mfundo yomwe ili mwana wamanzere wa kholo lake. Ganizirani nokha - fanizo lenileni.

Mlandu wachitatu. Node ali ndi ana awiri

Mlandu wovuta kwambiri. Tiyeni tione chitsanzo chatsopano.

Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Sakani wolowa m'malo

Tinene kuti tiyenera kuchotsa mfundo ndi kiyi 25. Kodi tiyenera kumuyika ndani m'malo mwake? Mmodzi mwa otsatira ake (mbadwa kapena zidzukulu) ayenera kukhala wolowa m'malo(amene adzatenge malo ochotsedwa mfundo).

Momwe mungamvetsetse yemwe ayenera kukhala wolowa m'malo? Mwachidziwitso, iyi ndi mfundo mumtengo womwe kiyi yake ndi yayikulu kwambiri pamfundo yomwe ikuchotsedwa. Algorithm ili motere. Muyenera kupita ku mbadwa yake yakumanja (nthawi zonse kumanja, chifukwa zanenedwa kale kuti fungulo lolowa m'malo ndilokulirapo kuposa fungulo la nodi likuchotsedwa), ndiyeno pitani ku unyolo wa mbadwa zakumanzere za mbadwa yakumanja iyi. . Mu chitsanzo, timapita ku mfundo ndi fungulo 35, ndiyeno kupita ku tsamba kudzera mu unyolo wa ana ake akumanzere - mu nkhani iyi, unyolo umangokhala mfundo ndi kiyi 30. Kunena zoona, ife tikuyang'ana. kwa mfundo yaying'ono kwambiri mumagulu akuluakulu kuposa omwe tikuyang'ana mfundo.

Binary Tree kapena momwe mungakonzekerere mtengo wosakira bayinare

Kodi njira yosakira m'malo:

    public Node<T> getSuccessor(Node<T> deleteNode) {
        Node<T> parentSuccessor = deleteNode;//Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊΠ°
        Node<T> successor = deleteNode;//ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊ
        Node<T> current = successor.getRightChild();//просто "ΠΏΡ€ΠΎΠ±Π΅Π³Π°ΡŽΡ‰ΠΈΠΉ" ΡƒΠ·Π΅Π»
        while (current != null) {
            parentSuccessor = successor;
            successor = current;
            current = current.getLeftChild();
        }
        //Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· Ρ†ΠΈΠΊΠ»Π° ΠΈΠΌΠ΅Π΅ΠΌ ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊΠ° ΠΈ родитСля ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊΠ°
        if (successor != deleteNode.getRightChild()) {//Ссли ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊ Π½Π΅ совпадаСт с ΠΏΡ€Π°Π²Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠΌ удаляСмого ΡƒΠ·Π»Π°
            parentSuccessor.setLeftChild(successor.getRightChild());//Ρ‚ΠΎ Π΅Π³ΠΎ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ Π·Π°Π±ΠΈΡ€Π°Π΅Ρ‚ сСбС ΠΏΠΎΡ‚ΠΎΠΌΠΊΠ° ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊΠ°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΠΎΡ‚Π΅Ρ€ΡΡ‚ΡŒ Π΅Π³ΠΎ
            successor.setRightChild(deleteNode.getRightChild());//связываСм ΠΏΡ€Π΅Π΅ΠΌΠ½ΠΈΠΊΠ° с ΠΏΡ€Π°Π²Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠΌ удаляСмого ΡƒΠ·Π»Π°
        }
        return successor;
    }

Khodi yonse ya njira yochotsera:

public boolean delete(int deleteKey) {
        Node<T> current = root;
        Node<T> parent = current;
        boolean isLeftChild = false;//Π’ зависимости ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, являСтся Π»ΠΈ  удаляСмый ΡƒΠ·Π΅Π» Π»Π΅Π²Ρ‹ΠΌ ΠΈΠ»ΠΈ ΠΏΡ€Π°Π²Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΌΠΊΠΎΠΌ своСго родитСля, булСвская пСрСмСнная isLeftChild Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ true ΠΈΠ»ΠΈ false соотвСтствСнно.
        while (current.getKey() != deleteKey) {
            parent = current;
            if (deleteKey < current.getKey()) {
                current = current.getLeftChild();
                isLeftChild = true;
            } else {
                isLeftChild = false;
                current = current.getRightChild();
            }
            if (current == null)
                return false;
        }

        if (current.getLeftChild() == null && current.getRightChild() == null) {//ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ случай
            if (current == root)
                current = null;
            else if (isLeftChild)
                parent.setLeftChild(null);
            else
                parent.setRightChild(null);
        }
        else if (current.getRightChild() == null) {//Π²Ρ‚ΠΎΡ€ΠΎΠΉ случай
            if (current == root)
                root = current.getLeftChild();
            else if (isLeftChild)
                parent.setLeftChild(current.getLeftChild());
            else
                current.setRightChild(current.getLeftChild());
        } else if (current.getLeftChild() == null) {
            if (current == root)
                root = current.getRightChild();
            else if (isLeftChild)
                parent.setLeftChild(current.getRightChild());
            else
                parent.setRightChild(current.getRightChild());
        } 
        else {//Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ случай
            Node<T> successor = getSuccessor(current);
            if (current == root)
                root = successor;
            else if (isLeftChild)
                parent.setLeftChild(successor);
            else
                parent.setRightChild(successor);
        }
        return true;
    }

Kuvutaku kumatha kuyerekezedwa ndi O (logi(n)).

Kupeza zochuluka/zochepera mumtengo

Ndizodziwikiratu momwe mungapezere mtengo wocheperako / wopambana mumtengo - muyenera kusuntha motsatizana ndi unyolo wazinthu zakumanzere / zakumanja za mtengo, motsatana; mukafika pa pepala, idzakhala chinthu chochepa kwambiri / chochepa kwambiri.

    public Node<T> getMinimum(Node<T> startPoint) {
        Node<T> current = startPoint;
        Node<T> parent = current;
        while (current != null) {
            parent = current;
            current = current.getLeftChild();
        }
        return parent;
    }

    public Node<T> getMaximum(Node<T> startPoint) {
        Node<T> current = startPoint;
        Node<T> parent = current;
        while (current != null) {
            parent = current;
            current = current.getRightChild();
        }
        return parent;
    }

Kuvuta - O(logi(n))

Symmetrical bypass

Traversal akuyendera nsonga iliyonse yamtengo kuti achitepo kanthu.

Recursive symmetric traversal algorithm:

  1. Chitani kanthu pa mwana wakumanzere
  2. Chitanipo kanthu ndi inu nokha
  3. Chitanipo kanthu pa mwana woyenera

Code:

    public void inOrder(Node<T> current) {
        if (current != null) {
            inOrder(current.getLeftChild());
            System.out.println(current.getData() + " ");//Π—Π΄Π΅ΡΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ всС, Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ
            inOrder(current.getRightChild());
        }
    }

Pomaliza

Pomaliza! Ngati sindinafotokoze kalikonse kapena ndili ndi ndemanga, chonde tisiyeni mu ndemanga. Monga ndalonjeza, ndimapereka code yonse.

Node.java:

public class Node<T> {
    private T data;
    private int key;
    private Node<T> leftChild;
    private Node<T> rightChild;

    public Node(T data, int key) {
        this.data = data;
        this.key = key;
    }

    public void setLeftChild(Node<T> newNode) {
        leftChild = newNode;
    }

    public void setRightChild(Node<T> newNode) {
        rightChild = newNode;
    }

    public Node<T> getLeftChild() {
        return leftChild;
    }

    public Node<T> getRightChild() {
        return rightChild;
    }

    public T getData() {
        return data;
    }

    public int getKey() {
        return key;
    }
}

BinaryTree.java:

public class BinaryTree<T> {
    private Node<T> root;

    public Node<T> find(int key) {
        Node<T> current = root;
        while (current.getKey() != key) {
            if (key < current.getKey())
                current = current.getLeftChild();
            else
                current = current.getRightChild();
            if (current == null)
                return null;
        }
        return current;
    }

    public void insert(T insertData, int key) {
        Node<T> current = root;
        Node<T> parent;
        Node<T> newNode = new Node<>(insertData, key);
        if (root == null)
            root = newNode;
        else {
            while (true) {
                parent = current;
                if (key < current.getKey()) {
                    current = current.getLeftChild();
                    if (current == null) {
                         parent.setLeftChild(newNode);
                         return;
                    }
                }
                else {
                    current = current.getRightChild();
                    if (current == null) {
                        parent.setRightChild(newNode);
                        return;
                    }
                }
            }
        }
    }

    public Node<T> getMinimum(Node<T> startPoint) {
        Node<T> current = startPoint;
        Node<T> parent = current;
        while (current != null) {
            parent = current;
            current = current.getLeftChild();
        }
        return parent;
    }

    public Node<T> getMaximum(Node<T> startPoint) {
        Node<T> current = startPoint;
        Node<T> parent = current;
        while (current != null) {
            parent = current;
            current = current.getRightChild();
        }
        return parent;
    }

    public Node<T> getSuccessor(Node<T> deleteNode) {
        Node<T> parentSuccessor = deleteNode;
        Node<T> successor = deleteNode;
        Node<T> current = successor.getRightChild();
        while (current != null) {
            parentSuccessor = successor;
            successor = current;
            current = current.getLeftChild();
        }

        if (successor != deleteNode.getRightChild()) {
            parentSuccessor.setLeftChild(successor.getRightChild());
            successor.setRightChild(deleteNode.getRightChild());
        }
        return successor;
    }

    public boolean delete(int deleteKey) {
        Node<T> current = root;
        Node<T> parent = current;
        boolean isLeftChild = false;
        while (current.getKey() != deleteKey) {
            parent = current;
            if (deleteKey < current.getKey()) {
                current = current.getLeftChild();
                isLeftChild = true;
            } else {
                isLeftChild = false;
                current = current.getRightChild();
            }
            if (current == null)
                return false;
        }

        if (current.getLeftChild() == null && current.getRightChild() == null) {
            if (current == root)
                current = null;
            else if (isLeftChild)
                parent.setLeftChild(null);
            else
                parent.setRightChild(null);
        }
        else if (current.getRightChild() == null) {
            if (current == root)
                root = current.getLeftChild();
            else if (isLeftChild)
                parent.setLeftChild(current.getLeftChild());
            else
                current.setRightChild(current.getLeftChild());
        } else if (current.getLeftChild() == null) {
            if (current == root)
                root = current.getRightChild();
            else if (isLeftChild)
                parent.setLeftChild(current.getRightChild());
            else
                parent.setRightChild(current.getRightChild());
        } 
        else {
            Node<T> successor = getSuccessor(current);
            if (current == root)
                root = successor;
            else if (isLeftChild)
                parent.setLeftChild(successor);
            else
                parent.setRightChild(successor);
        }
        return true;
    }

    public void inOrder(Node<T> current) {
        if (current != null) {
            inOrder(current.getLeftChild());
            System.out.println(current.getData() + " ");
            inOrder(current.getRightChild());
        }
    }
}

PS

Kusintha kwa O (n)

Ambiri a inu mwina mwazindikira: bwanji ngati mupanga mtengowo kukhala wosakhazikika? Mwachitsanzo, ikani nodes ndi makiyi owonjezereka mumtengo: 1,2,3,4,5,6... Ndiye mtengowo udzafanana ndi mndandanda wolumikizidwa. Ndipo inde, mtengowo udzataya kapangidwe kake ka mtengo, ndipo chifukwa chake kukwanira kwa data. Kuvuta kwa kusaka, kuyika, ndi kufufuta kudzakhala kofanana ndi kwa mndandanda wolumikizidwa: O(n). Ichi ndi chimodzi mwa zofunika kwambiri, mwa lingaliro langa, kuipa kwa mitengo ya binary.

Ogwiritsa ntchito olembetsedwa okha ndi omwe angatenge nawo gawo pa kafukufukuyu. Lowani muakauntichonde.

Sindinakhalepo kwa nthawi yayitali, ndipo ndikufuna kudziwa kuti ndi nkhani ziti zomwe mukufuna kuwona zambiri?

  • Kapangidwe ka Data

  • Ma algorithms (DP, recursion, compression data, etc.)

  • Kugwiritsa ntchito mapangidwe a data ndi ma algorithms m'moyo weniweni

  • Kupanga Mapulogalamu a Android ku Java

  • Kupanga mapulogalamu a pa intaneti ku Java

Ogwiritsa 2 adavota. Wogwiritsa m'modzi adasala.

Chitsime: www.habr.com

Kuwonjezera ndemanga