Binary Tree ama sida loo diyaariyo geed raadinta binary

Hordhac

Maqaalkani wuxuu ku saabsan yahay geedaha raadinta binary. Waxaan dhawaan maqaal ka qoray cufnaanta xogta habka Huffman. Halkaas oo aan runtii fiiro gaar ah u lahayn geedaha binary, sababtoo ah hababka raadinta, gelinta, tirtirka ma ahayn kuwo khuseeya. Hadda waxaan go'aansaday inaan maqaal ka qoro geedaha. Waxaa laga yaabaa inaan bilaabi doono.

Geedku waa qaab-dhismeed xogeed oo ka kooban noodhyo ku xidhan cidhifyo. Waxaan dhihi karnaa in geedku yahay kiis gaar ah oo garaaf ah. Waa kan tusaale geed:

Binary Tree ama sida loo diyaariyo geed raadinta binary

Kani maaha geed raadin binary ah! Wax walba waa hoos goynta!

Eray bixin

Root

Xidid geed waa noodhka ugu sarreeya. Tusaalaha, tani waa noode A. Geedka dhexdiisa, hal waddo oo keliya ayaa u horseedi karta xididka ilaa nood kasta! Dhab ahaantii, node kasta waxaa loo qaddarin karaa inuu yahay xididka geed-hoosaadka u dhigma noodhkan.

Waalidiinta/faraca

Dhammaan qanjidhada marka laga reebo xididku waxay leeyihiin hal cidhif oo u horseedaya noodh kale. Noodka ka sarreeya noodhka hadda jira ayaa loo yaqaan waalid noodhkan. Node ku yaal ka hooseeya kan hadda oo ku xiran ayaa la yiraahdaa ku abtirsada noodhkan. Aan tusaale usoo qaadano. Qaado noodhka B, ka dib waalidkeed waxa uu noqon doonaa buro A, caruurteeduna waxay noqon doonaan nuurad D, E, iyo F.

Caleen

Noodka aan caruur lahayn waxaa loo yaqaannaa caleen geed. Tusaalaha, qanjidhada D, E, F, G, I, J, K waxay noqon doonaan caleemo.

Tani waa erey bixinta aasaasiga ah. Fikradaha kale ayaa laga hadli doonaa mar dambe. Haddaba, geedka binary-ga ahi waa geed ay noodu ka heli doonto wax ka badan laba carruur ah. Sida aad qiyaastay, geedka tusaale ahaan ma noqon doono binary, sababtoo ah qanjidhada B iyo H waxay leeyihiin wax ka badan laba carruur ah. Waa kan tusaale ahaan geedka binary:

Binary Tree ama sida loo diyaariyo geed raadinta binary

Noodhyada geedku waxay ka koobnaan karaan macluumaad kasta. Geedka raadinta binary waa geed binary ah oo leh sifooyinka soo socda:

  1. Labada geed-hoosaadka bidix iyo midig labaduba waa geedo raadin binary ah.
  2. Dhammaan qanjidhada bidix ee qanjirada gardarrada X waxay leeyihiin qiyamka muhiimka ah ee xogta oo ka yar qiimaha xogta muhiimka ah ee noode X laftiisa.
  3. Dhammaan qanjidhada hoose ee saxda ah ee noode aan sabayn X waxay leeyihiin qiyamka muhiimka ah ee xogta oo ka weyn ama la mid ah qiimaha furaha xogta ee noode X laftiisa.

Furaha - qaar ka mid ah astaamaha udubka (tusaale ahaan, tiro). Furaha ayaa loo baahan yahay si loo helo xubinta geedka uu furahani u dhigmo. Tusaalaha geedka raadinta binary:

Binary Tree ama sida loo diyaariyo geed raadinta binary

muuqaalka geedka

Markaan sii socdo, waxaan ku dari doonaa qaybo kood ah (laga yaabee inaan dhamaystirnayn) si aan u horumariyo fahamkaaga. Koodhka buuxa wuxuu ahaan doonaa dhamaadka maqaalka.

Geedku wuxuu ka samaysan yahay qandho. Qaab dhismeedka 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;
    }
//...ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΡƒΠ·Π»Π°
}

Nod kastaa wuxuu leeyahay laba carruur ah (waa suurtogal in ilmaha bidix iyo/ama carruurta midigta ahi ay buro noqon doonaan). Waxaa laga yaabaa inaad fahantay in kiiskan xogta nambarku ay tahay xogta lagu kaydiyay noodhka; furaha - furaha noodhka.

Waxaan ogaanay guntinka, hadda aan ka hadalno dhibaatooyinka adag ee geedaha. Halkan iyo hoosta, ereyga "geed" macnaheedu waa fikradda geed raadinta binary. Qaab dhismeedka geedka binary:

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

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

Gegida fasalka ahaan, waxaan u baahanahay oo kaliya xididka geedka, sababtoo ah xididka, adoo isticmaalaya hababka getLeftChild () iyo getRightChild (), waxaad heli kartaa meel kasta oo geedka ah.

Algorithms geed

Поиск

Aan nidhaahno waxaad leedahay geed la dhisay. Sidee lagu helaa curiyaha furaha furaha leh? Waxaad u baahan tahay inaad si isdaba joog ah uga guurto xididka geedka oo isbarbardhig qiimaha furaha iyo furaha noodhka soo socda: haddii furuhu ka yar yahay furaha noodhka soo socda, ka dibna u tag faraca bidix ee qanjirada, haddii ay ka badan tahay - dhanka midig, haddii furayaashu siman yihiin - noodhka la rabo ayaa la helay! Koodhka ku habboon:

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;
}

Haddii hadda uu noqdo mid aan waxba ka jirin, ka dib soo noqnoqoshada ayaa gaartay dhammaadka geedka (heerka fikradda, waxaad ku jirtaa meel aan jirin oo geedka ah - ilmo caleen ah).

Tixgeli hufnaanta algorithm search on geed dheellitiran (geed kaas oo noodes loo qaybiyo in ka badan ama ka yar si siman). Kadibna waxtarka raadinta wuxuu noqon doonaa O (log(n)), iyo saldhigga 2 logarithm. Fiiri: haddii ay jiraan curiyeyaasha n ku jira geed dheellitiran, markaa tani waxay ka dhigan tahay in uu jiri doono log (n) saldhigga 2 ee geedka. Iyo raadinta, hal tallaabo oo wareeg ah, waxaad hoos ugu dhacaysaa hal heer.

gelin

Haddii aad fahantay nuxurka raadinta, markaa kuguma adkaan doonto inaad fahamto gelinta. Kaliya waxaad u baahan tahay inaad hoos ugu dhaadhacdo caleenta geedka (sida waafaqsan xeerarka faraca ee lagu sharraxay raadinta) oo noqo farcankiisa - bidix ama midig, iyadoo ku xiran furaha. Hirgelinta:

   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;
                    }
                }
            }
        }
    }

Xaaladdan oo kale, marka lagu daro noodhka hadda jira, waa lagama maarmaan in la kaydiyo macluumaadka ku saabsan waalidka qanjidhada hadda jira. Marka hadda uu noqdo mid aan waxba ahayn, doorsoomiyaha waalidka ayaa ka koobnaan doona xaashida aan u baahanahay.
Waxtarka gelinta ayaa sida cad la mid noqon doona kan raadinta - O(log(n)).

Tirtir

Tirtiridda waa qalliinka ugu adag ee u baahan doona in lagu sameeyo geed. Waxaa cad in marka hore ay lagama maarmaan noqon doonto in la helo cunsurka aan ka saarayno. Laakiin markaa waa maxay? Haddii aan si fudud u dhigno tixraaceeda null, markaa waxaan lumin doonaa macluumaadka ku saabsan geedka hoose ee xididkiisu yahay noodhkan. Hababka goynta geedaha waxa loo qaybiyaa saddex xaaladood.

Kiiskii ugu horreeyay. Noolka la saarayaa ma laha carruur.

Haddii qanjirada la tirtirayo aysan carruur lahayn, waxay la macno tahay inay tahay caleen. Sidaa darteed, waxaad si fudud uga dhigi kartaa barxadda ilmaha bidix ama ubadka midig ee waalidkeed inay buray.

Kiis labaad. Noolka la saarayo wuxuu leeyahay hal ilmo

Kiiskan sidoo kale ma aha mid aad u adag. Aan u soo noqono tusaalaheenii. Ka soo qaad in aan u baahanahay in aan tirtirno curiye leh furaha 14. Ogow in maadaama uu yahay cunugga saxda ah ee noodhka leh furaha 10, markaa mid kasta oo ka mid ah farcankiisa (kiiskan, midka saxda ah) wuxuu lahaan doonaa fure ka weyn 10, markaa adiga si fudud ayuu uga "goyn karaa" geedka, oo wuxuu si toos ah ugu xidhi karaa waalidka ilmaha nudaha la tirtirayo, i.e. ku xidh noodhka furaha 10 ilaa noodhka 13. Xaaladdu waxay noqonaysaa mid la mid ah haddii aan tirtirno noodhka kaas oo ah ubadka bidix ee waalidkiis. Ka fakar naftaada - isbarbardhig sax ah.

Kiis saddexaad. Node wuxuu leeyahay laba carruur ah

Kiiskii ugu adkaa. Bal aan eegno tusaale cusub.

Binary Tree ama sida loo diyaariyo geed raadinta binary

Raadi kii bedeli lahaa

Aynu nidhaahno waxaan u baahanahay inaan ka saarno noodhka furaha 25. Yaan dhigeynaa booskiisa? Mid ka mid ah xertiisa (faraciisa ama faraca farcankiisa) waa inuu noqdaa dhaxal sugaha(midka qaadi doona meesha qanjirada laga saaray).

Sideed ku garan kartaa cidda noqonaysa beddelka? Dareen ahaan, kani waa udubka geedka kaas oo furihiisa uu yahay kan ugu weyn ee ka soo baxa qanjirada la saarayo. Algorithm waa sida soo socota. Waxaad u baahan tahay inaad u tagto ilmaheeda saxda ah (had iyo jeer midigta, sababtoo ah horay ayaa loo sheegay in furaha guusha uu ka weyn yahay furaha noodhka oo la tirtiro), ka dibna u gudub silsiladda carruurta bidix ee midigtan. ilmo. Tusaalaha, waa in aan aadnaa noodhka leh furaha 35, ka dibna u dhaadhacno silsiladda carruurteeda bidix ilaa caleen - kiiskan, silsiladani waxay ka kooban tahay kaliya qanjirada furaha 30. Si adag u hadla, waxaan raadineynaa noodhka ugu yar ee gunnada qanjidhada ah ee ka weyn noodhka la rabo.

Binary Tree ama sida loo diyaariyo geed raadinta binary

Habka raadinta beddelka:

    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;
    }

Koodhka habka tirtirka oo dhammaystiran:

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;
    }

Kakanaanta waxa lagu qiyaasi karaa O(log(n)).

Helitaanka ugu badnaan/ugu yaraan geed

Sida iska cad, sida loo helo qiimaha ugu yar / ugu sarreeya ee geedka - waxaad u baahan tahay inaad si isdaba joog ah u dhex marto silsiladda bidix / midig ee geedka, siday u kala horreeyaan; marka aad gaadho caleenta, waxa ay noqon doontaa curiyaha ugu yar/ugu badan.

    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;
    }

Kakanaanta - O (log(n))

Simmetric Bypass

Socdaalku waa booqasho lagu tago dariiq kasta oo geedka ka mid ah si wax loogu qabto.

Algorithm-ka-socod-simmetrical ee soo noqnoqda:

  1. Wax ka samee ilmaha bidix
  2. La falgeli naftaada
  3. Ku samee tallaabo ubadka saxda ah

Code:

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

gunaanad

Ugu dambeyntii! Haddii aanan sharxin wax ama faallooyin, markaa waxaan sugayaa faallooyinka. Sidii ballanku ahaa, halkan waa koodka oo dhammaystiran.

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

Hoosudhac ilaa O(n)

Qaar badan oo idinka mid ah ayaa laga yaabaa inaad dareenteen: ka waran haddii aad geedka ka dhigto mid aan dheellitirnayn? Tusaale ahaan, geli noono geedka leh furayaasha sii kordhaya: 1,2,3,4,5,6 Oo haa, geedku wuxuu lumin doonaa qaab-dhismeedka geedkiisa, oo markaa waxtarka helitaanka xogta. Kakanaanta hawlgallada goobidda, gelinta, iyo tirtiridda waxay la mid noqonayaan kuwa liiska ku xidhan: O(n). Tani waa mid ka mid ah kuwa ugu muhiimsan, fikradeyda, faa'iido darrada geedaha binary.

Isticmaalayaasha diiwaangashan oo keliya ayaa ka qaybqaadan kara sahanka. Soo gal, soo dhawoow.

Muddo dheer ma joogin HabrΓ©, waxaanan jeclaan lahaa inaan ogaado maqaallada ku saabsan mowduuca aad jeceshahay inaad wax badan ku aragto?

  • Qaab-dhismeedka Xogta

  • Algorithms (DP, soo noqnoqoshada, cufnaanta xogta, iwm.)

  • Codsiga qaab-dhismeedka xogta iyo algorithms ee nolosha dhabta ah

  • Barnaamijyada barnaamijyada android ee Java

  • Java Web Application Programming

2 isticmaale ayaa u codeeyay. 1 isticmaale waa ka aamusay.

Xigasho: www.habr.com

Add a comment