Binääripuu on epälineaarinen tietorakenne jossa kullakin solmulla on enintään kaksi lasta. Tässä artikkelissa käsittelemme kaikki binaaripuun perusteet, binaaripuun toiminnot, sen toteutuksen, edut ja haitat, jotka auttavat sinua ratkaisemaan kaikki binaaripuuhun perustuvat ongelmat.
Sisällysluettelo
- Mikä on binaaripuu?
- Binaaripuun esitys
- Binaaripuiden tyypit
- Toiminnot binääripuussa
- Aputoiminnot binääripuussa
- Binaaripuun käyttöönotto
- Binääripuutoimintojen monimutkaisuusanalyysi
- Binaaripuun edut
- Binaaripuun haitat
- Binaaripuun sovellukset
- Usein kysytyt kysymykset binaaripuusta
Mikä on binaaripuu?
Binääripuu on a puun tietorakenne (epälineaarinen) jossa jokaisella solmulla voi olla korkeintaan kaksi lasta joita kutsutaan nimellä vasen lapsi ja oikea lapsi .
Binääripuun ylintä solmua kutsutaan juuri , ja alimpia solmuja kutsutaan lähtee . Binääripuu voidaan visualisoida hierarkkisena rakenteena, jonka juuri on ylhäällä ja lehdet alhaalla.
Binaaripuun esitys
Jokaisella binaaripuun solmulla on kolme osaa:
- Data
- Osoitin vasemmalle lapselle
- Osoita oikeaa lasta
Alla on esitys binääripuun solmusta eri kielillä:
C++ // Use any below method to implement Nodes of tree // Method 1: Using 'struct' to make // user-define data type struct node { int data; struct node* left; struct node* right; }; // Method 2: Using 'class' to make // user-define data type class Node { public: int data; Node* left; Node* right; };> C // Structure of each node of the tree struct node { int data; struct node* left; struct node* right; };> Java // Class containing left and right child // of current node and key value class Node { int key; Node left, right; public Node(int item) { key = item; left = right = null; } }> Python # A Python class that represents # an individual node in a Binary Tree class Node: def __init__(self, key): self.left = None self.right = None self.val = key>
C# // Class containing left and right child // of current node and key value class Node { int key; Node left, right; public Node(int item) { key = item; left = right = null; } }> JavaScript >> Binaaripuiden tyypit
Binääripuu voidaan luokitella useisiin tyyppeihin useiden tekijöiden perusteella:
- Lasten määrän perusteella
- Täysi binääripuu
- Degeneroitunut binääripuu
- Vino binaaripuut
- Tasojen suorittamisen perusteella
- Täydellinen binääripuu
- Täydellinen binaaripuu
- Tasapainoinen binääripuu
- Solmuarvojen perusteella:
- Binäärihakupuu
- AVL puu
- Punainen musta puu
- B Puu
- B+ puu
- Segmenttipuu
Toiminnot binääripuussa
1. Lisäys binaaripuuhun
Voimme lisätä solmun mihin tahansa binääripuuhun lisäämällä solmun minkä tahansa solmun vasemmaksi tai oikeaksi lapseksi tai tekemällä solmun puun juureksi.
Algoritmi solmun lisäämiseksi binaaripuuhun:
- Tarkista, onko binääripuussa solmu, josta puuttuu vasen lapsi. Jos tällainen solmu on olemassa, lisää uusi solmu sen vasemmaksi ali.
- Tarkista, onko binääripuussa solmu, josta puuttuu oikea lapsi. Jos tällainen solmu on olemassa, lisää uusi solmu sen oikeana alapuolena.
- Jos emme löydä solmua, josta puuttuu vasen tai oikea lapsi, etsi se solmu, josta molemmat lapset puuttuvat, ja lisää solmu vasemmaksi tai oikeaksi lapsekseen.
2. Binaaripuun läpikulku
Binaaripuun läpikäyminen sisältää vierailun binääripuun kaikissa solmuissa. Tree Traversal -algoritmit voidaan luokitella laajasti kahteen luokkaan:
- Depth-First Search (DFS) -algoritmit
- Breadth-First Search (BFS) -algoritmit
Depth-First Search (DFS) -algoritmit:
- Ennakkotilausmatka (nykyinen-vasen-oikea): Vieraile nykyisessä solmussa ennen kuin vierailet vasemman tai oikean alipuun sisällä olevissa solmuissa. Tässä läpikulku on juuri – vasen lapsi – oikea lapsi. Se tarkoittaa, että juurisolmu ajetaan ensin, sitten sen vasen lapsi ja lopuksi oikea lapsi.
- Tilauksen läpikulku (vasen-virta-oikea): Vieraile nykyisessä solmussa käytyäsi kaikissa vasemman alipuun sisällä olevissa solmuissa, mutta ennen kuin vierailet missä tahansa oikean alipuun solmussa. Tässä läpikulku on vasen lapsi – juuri – oikea lapsi. Se tarkoittaa, että ensin ajetaan vasen lapsi, sitten sen juurisolmu ja lopuksi oikea lapsi.
- Postorder Traversal (vasen-oikea-virta): Vieraile nykyisessä solmussa, kun olet käynyt kaikissa vasemman ja oikean alipuun solmuissa. Tässä läpikulku on vasen lapsi – oikea lapsi – juuri. Se tarkoittaa, että vasen lapsi on kulkenut ensin, sitten oikea lapsi ja lopuksi sen juurisolmu.
Breadth-First Search (BFS) -algoritmit:
- Tasotilauksen läpikulku: Vieraile solmuissa taso kerrallaan ja vasemmalta oikealle samalla tasolla. Tässä läpikulku on tasaista. Se tarkoittaa, että vasemmanpuoleisin lapsi on kulkenut ensin ja sitten muut saman tason lapset vasemmalta oikealle.
3. Poistaminen binääripuussa
Voimme poistaa minkä tahansa solmun binääripuusta ja järjestää solmut uudelleen poistamisen jälkeen muodostamaan jälleen kelvollisen binääripuun.
Algoritmi solmun poistamiseksi binääripuusta:
- Alkaen juuresta, etsi binääripuun syvin ja oikeanpuoleisin solmu ja solmu, jonka haluamme poistaa.
- Korvaa syvimmän oikeanpuoleisen solmun tiedot poistettavalla solmulla.
- Poista sitten syvin oikealla oleva solmu.
4. Haku binääripuusta
Voimme etsiä elementtiä solmusta käyttämällä mitä tahansa läpikulkutekniikkaa.
hrithik roshan
Algoritmi solmun etsimiseksi binääripuusta:
- Aloita juurisolmusta.
- Tarkista, onko nykyisen solmun arvo sama kuin tavoitearvo.
- Jos nykyisen solmun arvo on yhtä suuri kuin tavoitearvo, tämä solmu on vaadittu solmu.
- Muussa tapauksessa, jos solmun arvo ei ole sama kuin tavoitearvo, aloita haku vasemmasta ja oikeasta lapsesta.
- Jos emme löydä solmua, jonka arvo on sama kuin kohde, arvoa ei ole puussa.
Aputoiminnot binääripuussa
- Puun korkeuden löytäminen
- Etsi solmun taso binaaripuusta
- Koko puun koon selvittäminen
Binaaripuun käyttöönotto
Alla on koodi binääripuun lisäämistä, poistamista ja läpikulkua varten:
C data); inorderTraversal(juuri->oikea); } // Preorder tree traversal (Root - Left - Right) void preorderTraversal(Solmu* root) { if (!root) return; printf('%d ', root-> data); preorderTraversal(juuri->vasen); preorderTraversal(juuri->oikea); } // Postorder tree traversal (vasen - oikea - juuri) void postorderTraversal(Solmu* root) { if (juuri == NULL) return; postorderTraversal(juuri->vasen); postorderTraversal(juuri->oikea); printf('%d ', root-> data); } // Tasojärjestyspuun funktio traversal void levelorderTraversal(Solmu* root) { if (juuri == NULL) return; // Jono tasojärjestyksen läpikulkuun Solmu* jono[100]; int edessä = 0, takana = 0; jono[taka++] = juuri; while (etu != taka) { Solmu* temp = jono[etu++]; printf('%d ', temp->data); // Työnnä vasen lapsi jonoon if (temp->left) queue[rear++] = temp->left; // Työnnä oikea lapsi jonoon if (temp->right) queue[taka++] = temp->oikea; } } /* Ohjaintoiminto tarkistaa yllä olevan algoritmin. */ int main() { Solmu* root = NULL; // Solmujen lisäys root = insert(root, 10); juuri = insert(juuri, 20); juuri = insert(juuri, 30); juuri = insert(juuri, 40); printf('Ennakkotilaus: '); preorderTraversal(root); printf('
Tilauksen läpikulku: '); inorderTraversal(juuri); printf('
Postorder traversal: '); postorderTraversal(juuri); printf('
Tasojärjestyksen läpikulku: '); levelorderTraversal(juuri); // Poista solmu data = 20 root = deletion(root, 20); printf('
Järjestyksen läpikulku poiston jälkeen: '); inorderTraversal(juuri); paluu 0; }> Java import java.util.LinkedList; import java.util.Queue; // Node class to define the structure of the node class Node { int data; Node left, right; // Parameterized Constructor Node(int val) { data = val; left = right = null; } } public class BinaryTree { // Function to insert nodes public static Node insert(Node root, int data) { // If tree is empty, new node becomes the root if (root == null) { root = new Node(data); return root; } // Queue to traverse the tree and find the position to // insert the node Queueq = uusi LinkedList(); q.offer(root); while (!q.isEmpty()) { Solmun lämpötila = q.poll(); // Lisää solmu emosolmun vasemmaksi lapsiksi if (temp.left == null) { temp.left = new Node(data); tauko; } // Jos vasen lapsi ei ole tyhjä, työnnä se // jonoon else q.offer(temp.left); // Lisää solmu emosolmun oikeaksi jälkeläiseksi if (temp.right == null) { temp.right = new Node(data); tauko; } // Jos oikea lapsi ei ole tyhjä, työnnä se // jonoon else q.offer(temp.right); } palauttaa juuri; } /*-toiminto poistaa annetun syvimmän solmun (d_solmu) binääripuusta */ public static void deletDeepest(Solmun juuri, Node d_node) { Jonoq = uusi LinkedList(); q.offer(root); // Tee tasojärjestyksen läpikulku viimeiseen solmuun Solmun temp; while (!q.isEmpty()) { temp = q.poll(); if (temp == d_solmu) { temp = null; d_solmu = nolla; palata; } if (temp.oikea != null) { if (temp.right == d_solmu) { temp.oikea = null; d_solmu = nolla; palata; } else q.offer(temp.right); } if (temp.left != null) { if (temp.left == d_node) { temp.left = null; d_solmu = nolla; palata; } else q.offer(temp.left); } } } /* toiminto poistaa elementin binääripuusta */ julkinen staattinen Solmun poisto(Solmun juuri, int avain) { if (juuri == null) return null; if (root.left == null && root.right == null) { if (root.data == avain) return null; muuten palauta juuri; } Jonoq = uusi LinkedList(); q.offer(root); Solmun lämpötila = uusi solmu(0); Solmu avain_solmu = null; // Tee tasojärjestyksen läpikulku löytääksesi syvimmän // solmun (temp) ja poistettavan solmun (key_node) while (!q.isEmpty()) { temp = q.poll(); if (temp.data == avain) key_node = temp; if (temp.left != null) q.offer(temp.left); if (lämp.oikea != null) q.offer(temp.right); } if (avainsolmu != tyhjä) { int x = temp.data; key_node.data = x; poistaDeepest(juuri, temp); } palauttaa juuri; } // Järjestyspuun läpikulku (vasen - juuri - oikea) public static void inorderTraversal(Solmujuuri) { if (juuri == null) return; inorderTraversal(root.left); System.out.print(root.data + ' '); inorderTraversal(root.right); } // Ennakkotilauspuun läpikulku (juuri - vasen - oikea) public static void preorderTraversal(Solmujuuri) { if (juuri == null) return; System.out.print(root.data + ' '); preorderTraversal(root.left); preorderTraversal(root.right); } // Postorder tree traversal (vasen - oikea - juuri) public static void postorderTraversal(Solmujuuri) { if (juuri == null) return; postorderTraversal(root.left); postorderTraversal(root.right); System.out.print(root.data + ' '); } // Tasojärjestyspuun läpikulkufunktio public static void levelorderTraversal(Solmujuuri) { if (juuri == null) return; // Jono tasotilauksen läpikulkuun Jonoq = uusi LinkedList(); q.offer(root); while (!q.isEmpty()) { Solmun lämpötila = q.poll(); System.out.print(temp.data + ' '); // Työnnä vasen lapsi jonoon if (temp.left != null) q.offer(temp.left); // Työnnä oikea lapsi jonoon if (temp.right != null) q.offer(temp.right); } } /* Ohjaintoiminto tarkistaa yllä olevan algoritmin. */ julkinen staattinen void main(String[] args) { Solmun juuri = null; // Solmujen lisäys root = insert(root, 10); juuri = insert(juuri, 20); juuri = insert(juuri, 30); juuri = insert(juuri, 40); System.out.print('Ennakkotilaus: '); preorderTraversal(root); System.out.print('
Inorder traversal: '); inorderTraversal(juuri); System.out.print('
Postorder traversal: '); postorderTraversal(juuri); System.out.print('
Tasojärjestyksen läpikulku: '); levelorderTraversal(juuri); // Poista solmu data = 20 root = deletion(root, 20); System.out.print('
Järjestyksen läpikulku poiston jälkeen: '); inorderTraversal(juuri); } }> Python from collections import deque # Node class to define the structure of the node class Node: def __init__(self, val): self.data = val self.left = self.right = None # Function to insert nodes def insert(root, data): # If tree is empty, new node becomes the root if root is None: root = Node(data) return root # Queue to traverse the tree and find the position to insert the node q = deque() q.append(root) while q: temp = q.popleft() # Insert node as the left child of the parent node if temp.left is None: temp.left = Node(data) break # If the left child is not null push it to the queue else: q.append(temp.left) # Insert node as the right child of parent node if temp.right is None: temp.right = Node(data) break # If the right child is not null push it to the queue else: q.append(temp.right) return root # Function to delete the given deepest node (d_node) in binary tree def deletDeepest(root, d_node): q = deque() q.append(root) # Do level order traversal until last node while q: temp = q.popleft() if temp == d_node: temp = None del d_node return if temp.right: if temp.right == d_node: temp.right = None del d_node return else: q.append(temp.right) if temp.left: if temp.left == d_node: temp.left = None del d_node return else: q.append(temp.left) # Function to delete element in binary tree def deletion(root, key): if not root: return None if root.left is None and root.right is None: if root.data == key: return None else: return root q = deque() q.append(root) temp = None key_node = None # Do level order traversal to find deepest node (temp) and node to be deleted (key_node) while q: temp = q.popleft() if temp.data == key: key_node = temp if temp.left: q.append(temp.left) if temp.right: q.append(temp.right) if key_node is not None: x = temp.data key_node.data = x deletDeepest(root, temp) return root # Inorder tree traversal (Left - Root - Right) def inorderTraversal(root): if not root: return inorderTraversal(root.left) print(root.data, end=' ') inorderTraversal(root.right) # Preorder tree traversal (Root - Left - Right) def preorderTraversal(root): if not root: return print(root.data, end=' ') preorderTraversal(root.left) preorderTraversal(root.right) # Postorder tree traversal (Left - Right - Root) def postorderTraversal(root): if root is None: return postorderTraversal(root.left) postorderTraversal(root.right) print(root.data, end=' ') # Function for Level order tree traversal def levelorderTraversal(root): if root is None: return # Queue for level order traversal q = deque() q.append(root) while q: temp = q.popleft() print(temp.data, end=' ') # Push left child in the queue if temp.left: q.append(temp.left) # Push right child in the queue if temp.right: q.append(temp.right) # Driver function to check the above algorithm if __name__ == '__main__': root = None # Insertion of nodes root = insert(root, 10) root = insert(root, 20) root = insert(root, 30) root = insert(root, 40) print('Preorder traversal:', end=' ') preorderTraversal(root) print('
Inorder traversal:', end=' ') inorderTraversal(root) print('
Postorder traversal:', end=' ') postorderTraversal(root) print('
Level order traversal:', end=' ') levelorderTraversal(root) # Delete the node with data = 20 root = deletion(root, 20) print('
Inorder traversal after deletion:', end=' ') inorderTraversal(root)> C# using System; using System.Collections.Generic; // Node class to define the structure of the node public class Node { public int data; public Node left, right; // Parameterized Constructor public Node(int val) { data = val; left = right = null; } } public class Program { // Function to insert nodes public static Node Insert(Node root, int data) { // If tree is empty, new node becomes the root if (root == null) { root = new Node(data); return root; } // Queue to traverse the tree and find the position to insert the node Queueq = uusi jono(); q.Enqueue(juuri); while (q.Count != 0) { Solmun lämpötila = q.Dequeue(); // Lisää solmu emosolmun vasemmaksi lapsiksi if (temp.left == null) { temp.left = new Node(data); tauko; } // Jos vasen lapsi ei ole tyhjä, työnnä se jonoon else q.Enqueue(temp.left); // Lisää solmu emosolmun oikeaksi jälkeläiseksi if (temp.right == null) { temp.right = new Node(data); tauko; } // Jos oikea lapsi ei ole tyhjä, työnnä se jonoon else q.Enqueue(temp.right); } palauttaa juuri; } /*-funktio poistaa annetun syvimmän solmun (d_solmu) binääripuusta */ public static void DeleteDeepest(Solmun juuri, Solmu d_solmu) { Jonoq = uusi jono(); q.Enqueue(juuri); // Tee tasojärjestyksen läpikulku viimeiseen solmuun Solmun temp; while (q.Count != 0) { temp = q.Dequeue(); if (temp == d_solmu) { temp = null; d_solmu = nolla; palata; } if (temp.oikea != null) { if (temp.right == d_solmu) { temp.oikea = null; d_solmu = nolla; palata; } else q.Enqueue(temp.right); } if (temp.left != null) { if (temp.left == d_node) { temp.left = null; d_solmu = nolla; palata; } else q.Enqueue(temp.left); } } } /* toiminto poistaa elementin binääripuusta */ julkinen staattinen Solmun poisto(Solmun juuri, int avain) { if (juuri == null) return null; if (root.left == null && root.right == null) { if (root.data == avain) return null; muuten palauta juuri; } Jonoq = uusi jono(); q.Enqueue(juuri); Solmun lämpötila = uusi solmu(0); Solmu avain_solmu = null; // Tee tasojärjestyksen läpikulku löytääksesi syvin solmun (temp) ja poistettavan solmun (avainsolmu), kun taas (q.Count != 0) { temp = q.Dequeue(); if (temp.data == avain) key_node = temp; if (temp.left != null) q.Enqueue(temp.left); if (temp.oikea != null) q.Enqueue(temp.right); } if (avainsolmu != tyhjä) { int x = temp.data; key_node.data = x; PoistaSyvin(juuri, temp); } palauttaa juuri; } // Järjestyspuun läpikulku (vasen - juuri - oikea) public static void InorderTraversal(Solmujuuri) { if (juuri == null) return; InorderTraversal(root.left); Console.Write(root.data + ' '); InorderTraversal(root.right); } // Ennakkotilauspuun läpikulku (juuri - vasen - oikea) public static void PreorderTraversal(Solmujuuri) { if (juuri == null) return; Console.Write(root.data + ' '); PreorderTraversal(root.left); PreorderTraversal(root.right); } // Postorder tree traversal (vasen - oikea - juuri) public static void PostorderTraversal(Solmujuuri) { if (juuri == null) return; PostorderTraversal(root.left); PostorderTraversal(root.right); Console.Write(root.data + ' '); } // Tasojärjestyspuun läpikulkufunktio public static void TasojärjestysTraversal(Solmujuuri) { if (juuri == null) return; // Jono tasotilauksen läpikulkuun Jonoq = uusi jono(); q.Enqueue(juuri); while (q.Count != 0) { Solmun lämpötila = q.Dequeue(); Console.Write(temp.data + ' '); // Työnnä vasen lapsi jonoon if (temp.left != null) q.Enqueue(temp.left); // Työnnä oikea lapsi jonoon if (temp.right != null) q.Enqueue(temp.right); } } /* Ohjaintoiminto tarkistaa yllä olevan algoritmin. */ public static void Main(merkkijono[] args) { Solmun juuri = null; // Solmujen lisääminen root = Insert(juuri, 10); juuri = Lisää(juuri, 20); juuri = Lisää(juuri, 30); juuri = Lisää(juuri, 40); Console.Write('Ennakkotilaus: '); EnnakkotilausTraversal(juuri); Console.Write('
Tilauksen läpikulku: '); InorderTraversal(juuri); Console.Write('
Postorder traversal: '); PostorderTraversal(juuri); Console.Write('
Tasojärjestyksen läpikulku: '); LevelorderTraversal(juuri); // Poista solmu datalla = 20 root = Poista (juuri, 20); Console.Write('
Järjestä läpikulku poiston jälkeen: '); InorderTraversal(juuri); } }> Javascript // Node class to define the structure of the node class Node { constructor(val) { this.data = val; this.left = null; this.right = null; } } // Function to insert nodes function insert(root, data) { // If tree is empty, new node becomes the root if (root === null) { root = new Node(data); return root; } // queue to traverse the tree and find the position to // insert the node const q = []; q.push(root); while (q.length !== 0) { const temp = q.shift(); // Insert node as the left child of the parent node if (temp.left === null) { temp.left = new Node(data); break; } // If the left child is not null push it to the // queue else q.push(temp.left); // Insert node as the right child of parent node if (temp.right === null) { temp.right = new Node(data); break; } // If the right child is not null push it to the // queue else q.push(temp.right); } return root; } /* function to delete the given deepest node (d_node) in binary tree */ function deletDeepest(root, d_node) { const q = []; q.push(root); // Do level order traversal until last node let temp; while (q.length !== 0) { temp = q.shift(); if (temp === d_node) { temp = null; delete d_node; return; } if (temp.right) { if (temp.right === d_node) { temp.right = null; delete d_node; return; } else q.push(temp.right); } if (temp.left) { if (temp.left === d_node) { temp.left = null; delete d_node; return; } else q.push(temp.left); } } } /* function to delete element in binary tree */ function deletion(root, key) { if (!root) return null; if (root.left === null && root.right === null) { if (root.data === key) return null; else return root; } const q = []; q.push(root); let temp; let key_node = null; // Do level order traversal to find deepest // node(temp) and node to be deleted (key_node) while (q.length !== 0) { temp = q.shift(); if (temp.data === key) key_node = temp; if (temp.left) q.push(temp.left); if (temp.right) q.push(temp.right); } if (key_node !== null) { const x = temp.data; key_node.data = x; deletDeepest(root, temp); } return root; } // Inorder tree traversal (Left - Root - Right) function inorderTraversal(root) { if (!root) return; inorderTraversal(root.left); console.log(root.data + ' '); inorderTraversal(root.right); } // Preorder tree traversal (Root - Left - Right) function preorderTraversal(root) { if (!root) return; console.log(root.data + ' '); preorderTraversal(root.left); preorderTraversal(root.right); } // Postorder tree traversal (Left - Right - Root) function postorderTraversal(root) { if (root === null) return; postorderTraversal(root.left); postorderTraversal(root.right); console.log(root.data + ' '); } // Function for Level order tree traversal function levelorderTraversal(root) { if (root === null) return; // Queue for level order traversal const q = []; q.push(root); while (q.length !== 0) { const temp = q.shift(); console.log(temp.data + ' '); // Push left child in the queue if (temp.left) q.push(temp.left); // Push right child in the queue if (temp.right) q.push(temp.right); } } /* Driver function to check the above algorithm. */ let root = null; // Insertion of nodes root = insert(root, 10); root = insert(root, 20); root = insert(root, 30); root = insert(root, 40); console.log('Preorder traversal: '); preorderTraversal(root); console.log('
Inorder traversal: '); inorderTraversal(root); console.log('
Postorder traversal: '); postorderTraversal(root); console.log('
Level order traversal: '); levelorderTraversal(root); // Delete the node with data = 20 root = deletion(root, 20); console.log('
Inorder traversal after deletion: '); inorderTraversal(root);> C++14 #include using namespace std; // Node class to define the structure of the node class Node { public: int data; Node *left, *right; // Parameterized Constructor Node(int val) { data = val; left = right = NULL; } }; // Function to insert nodes Node* insert(Node* root, int data) { // If tree is empty, new node becomes the root if (root == NULL) { root = new Node(data); return root; } // queue to traverse the tree and find the position to // insert the node queueq; q.push(juuri); while (!q.empty()) { Solmu* temp = q.front(); q.pop(); // Lisää solmu emosolmun vasemmaksi lapseksi if (temp->left == NULL) { temp->left = new Node(data); tauko; } // Jos vasen lapsi ei ole tyhjä, työnnä se // jonoon else q.push(temp->left); // Lisää solmu emosolmun oikeaksi jälkeläiseksi if (temp->right == NULL) { temp->right = new Node(data); tauko; } // Jos oikea lapsi ei ole tyhjä, työnnä se // jonoon else q.push(temp->right); } palauttaa juuri; } /*-funktio poistaa annetun syvimmän solmun (d_solmu) binääripuusta */ void deletDeepest(Solmu* root, Node* d_node) { jonoq; q.push(juuri); // Tee tasojärjestyksen läpikulku viimeiseen solmuun Solmu* temp; while (!q.empty()) { temp = q.front(); q.pop(); if (temp == d_solmu) { temp = NULL; poista (d_solmu); palata; } if (lämp->oikea) { if (lämp->oikea == d_solmu) { temp->oikea = NULL; poista (d_solmu); palata; } else q.push(temp->right); } if (temp->vasen) { if (temp->left == d_solmu) { temp->vasen = NULL; poista (d_solmu); palata; } else q.push(temp->left); } } } /*-toiminto poistaa elementin binääripuusta */ Node* deletion(Solmu* root, int avain) { if (!root) return NULL; if (juuri->vasen == NULL && juuri->oikea == NULL) { if (root->data == avain) return NULL; muuten palauta juuri; } jonossaq; q.push(juuri); Solmu* lämpötila; Node* key_node = NULL; // Tee tasojärjestyksen läpikulku löytääksesi syvimmän // solmun (temp) ja poistettavan solmun (key_node) while (!q.empty()) { temp = q.front(); q.pop(); if (temp->data == avain) key_node = temp; if (temp->left) q.push(temp->left); if (lämpö->oikea) q.push(temp->right); } if (avainsolmu != NULL) { int x = temp->data; avain_solmu->tiedot = x; poistaSyvin(juuri, temp); } palauttaa juuri; } // Järjestyspuun läpikulku (vasen - juuri - oikea) void inorderTraversal(Solmu* juuri) { if (!root) return; inorderTraversal(juuri->vasen); cout<< root->tiedot<< ' '; inorderTraversal(root->oikea); } // Preorder tree traversal (Root - Left - Right) void preorderTraversal(Solmu* root) { if (!root) return; cout<< root->tiedot<< ' '; preorderTraversal(root->vasen); preorderTraversal(juuri->oikea); } // Postorder tree traversal (vasen - oikea - juuri) void postorderTraversal(Solmu* root) { if (juuri == NULL) return; postorderTraversal(juuri->vasen); postorderTraversal(juuri->oikea); cout<< root->tiedot<< ' '; } // Function for Level order tree traversal void levelorderTraversal(Node* root) { if (root == NULL) return; // Queue for level order traversal queueq; q.push(juuri); while (!q.empty()) { Solmu* temp = q.front(); q.pop(); cout<< temp->tiedot<< ' '; // Push left child in the queue if (temp->vasen) q.push(temp->left); // Työnnä oikea lapsi jonossa if (temp->right) q.push(temp->right); } } /* Ohjaintoiminto tarkistaa yllä olevan algoritmin. */ int main() { Solmu* root = NULL; // Solmujen lisäys root = insert(root, 10); juuri = insert(juuri, 20); juuri = insert(juuri, 30); juuri = insert(juuri, 40); cout<< 'Preorder traversal: '; preorderTraversal(root); cout << '
Inorder traversal: '; inorderTraversal(root); cout << '
Postorder traversal: '; postorderTraversal(root); cout << '
Level order traversal: '; levelorderTraversal(root); // Delete the node with data = 20 root = deletion(root, 20); cout << '
Inorder traversal after deletion: '; inorderTraversal(root); }> Lähtö
Preorder traversal: 10 20 40 30 Inorder traversal: 40 20 10 30 Postorder traversal: 40 20 30 10 Level order traversal: 10 20 30 40 Inorder traversal after deletion: 40 10 30>
Binääripuutoimintojen monimutkaisuusanalyysi
| Toiminnot | Aika monimutkaisuus | Avaruuden monimutkaisuus |
|---|---|---|
| Lisäys | PÄÄLLÄ) | PÄÄLLÄ) |
| Ennakkotilaa Traversal | PÄÄLLÄ) | PÄÄLLÄ) |
Inorder Traversal | PÄÄLLÄ) | PÄÄLLÄ) vertaa javaan |
| Postimääräyksen läpikulku | PÄÄLLÄ) | PÄÄLLÄ) |
| Tasojärjestyksen läpikäynti | PÄÄLLÄ) | PÄÄLLÄ) |
Poistaminen | PÄÄLLÄ) | PÄÄLLÄ) |
Etsitään | PÄÄLLÄ) | PÄÄLLÄ) |
Voimme käyttää Morris Traversal kulkea kaikki binääripuun solmut O(1)-ajassa.
lisäämällä merkkijonoa javassa
Binaaripuun edut
- Tehokas haku: Binaaripuut ovat tehokkaita haettaessa tiettyä elementtiä, koska jokaisessa solmussa on enintään kaksi lapsisolmua, mikä mahdollistaa Muistitehokas: Binääripuut vaativat vähemmän muistia verrattuna muihin puutietorakenteisiin, joten ne ovat muistitehokkaita.
- Binääripuut ovat suhteellisen helppoja toteuttaa ja ymmärtää, koska jokaisella solmulla on enintään kaksi lasta, vasen lapsi ja oikea lapsi.
Binaaripuun haitat
- Rajoitettu rakenne: Binaaripuut on rajoitettu kahteen lapsisolmuun solmua kohti, mikä voi rajoittaa niiden käyttökelpoisuutta tietyissä sovelluksissa. Jos esimerkiksi puu vaatii enemmän kuin kaksi lapsisolmua solmua kohti, eri puurakenne voi olla sopivampi.
- Epätasapainoiset puut: Epätasapainoiset binääripuut, joissa yksi alipuu on huomattavasti suurempi kuin toinen, voivat johtaa tehottomiin hakutoimintoihin. Tämä voi tapahtua, jos puu ei ole kunnolla tasapainotettu tai jos tiedot on lisätty ei-satunnaisessa järjestyksessä.
- Tilan tehottomuus: Binaaripuut voivat olla tilatehottomia muihin tietorakenteisiin verrattuna. Tämä johtuu siitä, että jokainen solmu vaatii kaksi aliosoitinta, mikä voi olla huomattava määrä muistia suurille puille.
- Hidas suorituskyky pahimmassa tapauksessa: Pahimmassa tapauksessa binääripuu voi rappeutua tai vääristyä, mikä tarkoittaa, että jokaisella solmulla on vain yksi lapsi. Tässä tapauksessa hakuoperaatiot voivat heikentyä O(n)-aikaiseen monimutkaisuuteen, missä n on puun solmujen lukumäärä.
Binaaripuun sovellukset
- Binääripuuta voidaan käyttää edustavat hierarkkista dataa .
- Huffman Coding -puita käytetään tietojen pakkausalgoritmit .
- Prioriteettijono on toinen binääripuun sovellus, jota käytetään maksimi- tai minimihakuun O(1)-aikakompleksisuudessa.
- Hyödyllinen tietokannassa segmentoitu indeksointi on hyödyllinen välimuistin tallentamisessa järjestelmään,
- Binääripuita voidaan käyttää päätöspuiden toteuttamiseen, eräänlainen koneoppimisalgoritmi, jota käytetään luokitteluun ja regressioanalyysiin.
Usein kysytyt kysymykset binaaripuusta
1. Mikä on binääripuu?
Binääripuu on solmuista koostuva epälineaarinen tietorakenne, jossa kullakin solmulla on enintään kaksi lasta (vasen lapsi ja oikea lapsi).
2. Mitkä ovat binääripuiden tyypit?
Binääripuut voidaan luokitella eri tyyppeihin, mukaan lukien täydelliset binääripuut, täydelliset binääripuut, täydelliset binääripuut, tasapainotetut binääripuut (kuten AVL-puut ja puna-mustat puut) ja rappeutuneet (tai patologiset) binaaripuut.
3. Mikä on binääripuun korkeus?
Binääripuun korkeus on pisimmän polun pituus juurisolmusta lehtisolmuun. Se edustaa reunojen määrää pisimmällä polulla juurisolmusta lehtisolmuun.
4. Mikä on solmun syvyys binääripuussa?
Binääripuun solmun syvyys on polun pituus juurisolmusta kyseiseen solmuun. Juurisolmun syvyys on 0.
5. Kuinka suoritat puun läpikulkua binääripuussa?
Puun läpikulku binääripuussa voidaan tehdä eri tavoilla: järjestyksessä läpikulku, ennakkotilausläpikulku, tilauksen jälkeinen läpikulku ja tasojärjestyksen läpikulku (tunnetaan myös nimellä leveys-ensimmäinen läpikulku).
6. Mikä on Inorder-läpikulku binääripuussa?
Inorder traversalissa solmuissa käydään rekursiivisesti tässä järjestyksessä: vasen lapsi, juuri, oikea lapsi. Tämän läpikäynnin seurauksena solmuissa käydään ei-laskevassa järjestyksessä binäärihakupuussa.
7. Mikä on ennakkotilauskierros binaaripuussa?
Ennakkotilauksen läpikäymisessä solmuissa käydään rekursiivisesti tässä järjestyksessä: juuri, vasen lapsi, oikea lapsi. Tämä läpikulku johtaa siihen, että juurisolmu on ensimmäinen solmu, jossa käydään.
8. Mikä on postorder-läpikulku binääripuussa?
Postorder traversalissa solmuissa käydään rekursiivisesti tässä järjestyksessä: vasen lapsi, oikea lapsi ja juuri. Tämä läpikulku johtaa siihen, että juurisolmu on viimeinen solmu, jossa käydään.
9. Mitä eroa on binääripuulla ja binäärihakupuulla?
Binääripuu on hierarkkinen tietorakenne, jossa jokaisella solmulla on korkeintaan kaksi alaosaa, kun taas binäärihakupuu on binääripuutyyppi, jossa solmun vasen lapsi sisältää arvoja pienempiä kuin solmun arvo ja oikea lapsi sisältää arvoja. suurempi kuin solmun arvo.
10. Mikä on tasapainoinen binääripuu?
Tasapainotettu binääripuu on binääripuu, jossa jokaisen solmun vasemman ja oikean alipuun korkeus eroaa korkeintaan yhdellä. Tasapainotetut puut auttavat ylläpitämään tehokkaita toimintoja, kuten etsimistä, lisäämistä ja poistamista aikamonimutkaisuuden ollessa lähellä O(log n:tä).
Johtopäätös:
Puu on hierarkkinen tietorakenne. Puiden pääasiallisia käyttötarkoituksia ovat hierarkkisten tietojen ylläpito, kohtuullisen pääsyn tarjoaminen ja lisäys/poistotoiminnot. Binääripuut ovat puun erikoistapauksia, joissa jokaisella solmulla on enintään kaksi lasta.
Aiheeseen liittyvät artikkelit:
- Binaaripuun ominaisuudet
- Binaaripuiden tyypit