B-boom

In deze tutorial leer je wat een B-tree is. Ook vindt u werkende voorbeelden van zoekbewerkingen op een B-tree in C, C ++, Java en Python.

B-tree is een speciaal type zelfbalancerende zoekboom waarin elk knooppunt meer dan één sleutel kan bevatten en meer dan twee kinderen. Het is een gegeneraliseerde vorm van de binaire zoekboom.

Het is ook bekend als een in hoogte gebalanceerde m-way tree.

B-boom

Waarom B-tree?

De behoefte aan B-tree ontstond met de toenemende behoefte aan minder tijd om toegang te krijgen tot de fysieke opslagmedia zoals een harde schijf. De secundaire opslagapparaten zijn langzamer met een grotere capaciteit. Er was behoefte aan dergelijke soorten datastructuren die de toegang tot de schijf minimaliseren.

Andere datastructuren zoals een binaire zoekboom, avl boom, rood-zwarte boom, enz. Kunnen slechts één sleutel in één knooppunt opslaan. Als u een groot aantal sleutels moet opslaan, wordt de hoogte van dergelijke bomen erg groot en neemt de toegangstijd toe.

B-tree kan echter veel sleutels in één knooppunt opslaan en kan meerdere onderliggende knooppunten hebben. Dit vermindert de hoogte aanzienlijk, waardoor snellere schijftoegang mogelijk is.

B-tree eigenschappen

  1. Voor elk knooppunt x worden de sleutels in oplopende volgorde opgeslagen.
  2. In elk knooppunt is er een booleaanse waarde x.leaf die waar is als x een blad is.
  3. Als n de volgorde van de boom is, kan elk intern knooppunt maximaal n - 1 sleutels bevatten, samen met een wijzer naar elk kind.
  4. Elk knooppunt behalve root kan maximaal n kinderen hebben en minimaal n / 2 kinderen.
  5. Alle bladeren hebben dezelfde diepte (dwz hoogte-h van de boom).
  6. De wortel heeft minimaal 2 kinderen en bevat minimaal 1 sleutel.
  7. Als n 1 ≧, daarna naar n-key B-structuur van de hoogte h en de minimale t ≧ 2, .h ≧ logt (n+1)/2

Operaties

Zoeken

Zoeken naar een element in een B-boomstructuur is de algemene vorm van het zoeken naar een element in een binaire zoekboom. De volgende stappen worden gevolgd.

  1. Vergelijk k vanaf het hoofdknooppunt met de eerste sleutel van het knooppunt.
    Als k = the first key of the node, retourneer het knooppunt en de index.
  2. Als k.leaf = true, retourneer NULL (dwz niet gevonden).
  3. If k < the first key of the root node, zoek recursief het linkerkind van deze sleutel.
  4. Als er meer dan één sleutel in het huidige knooppunt en is k> the first key, vergelijk k dan met de volgende sleutel in het knooppunt.
    If k < next key, zoek het linkerkind van deze sleutel (dwz. K ligt tussen de eerste en tweede sleutel).
    Zoek anders het juiste kind van de sleutel.
  5. Herhaal stap 1 t / m 4 totdat het blad is bereikt.

Zoekvoorbeeld

  1. Laten we de sleutel zoeken k = 17in de boom hieronder van graad 3. B-boom
  2. k wordt niet gevonden in de root, dus vergelijk het met de root key. k wordt niet gevonden op het hoofdknooppunt
  3. k> 11Ga sindsdien naar het rechterkind van het hoofdknooppunt. Ga naar de juiste substructuur
  4. Vergelijk k met 16. Vergelijk k sindsdien k> 16met de volgende toets 18. Vergelijk met de toetsen van links naar rechts
  5. Aangezien k < 18k tussen 16 en 18 ligt. Zoek in het rechterkind van 16 of het linkerkind van 18. k ligt tussen 16 en 18
  6. k wordt gevonden. k wordt gevonden

Algoritme voor het zoeken naar een element

 BtreeSearch(x, k) i = 1 while i ≦ n(x) and k ≧ keyi(x) // n(x) means number of keys in x node do i = i + 1 if i n(x) and k = keyi(x) then return (x, i) if leaf (x) then return NIL else return BtreeSearch(ci(x), k) 

Ga naar voor meer informatie over verschillende B-tree-bewerkingen

  • Invoegen op B-boom
  • Verwijdering op B-tree

Python, Java en C / C ++ voorbeelden

Python Java C C ++
# Searching a key on a B-tree in Python # Create node class BTreeNode: def __init__(self, leaf=False): self.leaf = leaf self.keys = () self.child = () class BTree: def __init__(self, t): self.root = BTreeNode(True) self.t = t # Print the tree def print_tree(self, x, l=0): print("Level ", l, " ", len(x.keys), end=":") for i in x.keys: print(i, end=" ") print() l += 1 if len(x.child)> 0: for i in x.child: self.print_tree(i, l) # Search key def search_key(self, k, x=None): if x is not None: i = 0 while i x.keys(i)(0): i += 1 if i  = 0 and k(0)  = 0 and k(0)  x.keys(i)(0): i += 1 self.insert_non_full(x.child(i), k) # Split def split(self, x, i): t = self.t y = x.child(i) z = BTreeNode(y.leaf) x.child.insert_key(i + 1, z) x.keys.insert_key(i, y.keys(t - 1)) z.keys = y.keys(t: (2 * t) - 1) y.keys = y.keys(0: t - 1) if not y.leaf: z.child = y.child(t: 2 * t) y.child = y.child(0: t - 1) def main(): B = BTree(3) for i in range(10): B.insert_key((i, 2 * i)) B.print_tree(B.root) if B.search_key(8) is not None: print("Found") else: print("Not found") if __name__ == '__main__': main()   
 // Searching a key on a B-tree in Java public class BTree ( private int T; // Node creation public class Node ( int n; int key() = new int(2 * T - 1); Node child() = new Node(2 * T); boolean leaf = true; public int Find(int k) ( for (int i = 0; i < this.n; i++) ( if (this.key(i) == k) ( return i; ) ) return -1; ); ) public BTree(int t) ( T = t; root = new Node(); root.n = 0; root.leaf = true; ) private Node root; // Search key private Node Search(Node x, int key) ( int i = 0; if (x == null) return x; for (i = 0; i < x.n; i++) ( if (key < x.key(i)) ( break; ) if (key == x.key(i)) ( return x; ) ) if (x.leaf) ( return null; ) else ( return Search(x.child(i), key); ) ) // Splitting the node private void Split(Node x, int pos, Node y) ( Node z = new Node(); z.leaf = y.leaf; z.n = T - 1; for (int j = 0; j < T - 1; j++) ( z.key(j) = y.key(j + T); ) if (!y.leaf) ( for (int j = 0; j = pos + 1; j--) ( x.child(j + 1) = x.child(j); ) x.child(pos + 1) = z; for (int j = x.n - 1; j>= pos; j--) ( x.key(j + 1) = x.key(j); ) x.key(pos) = y.key(T - 1); x.n = x.n + 1; ) // Inserting a value public void Insert(final int key) ( Node r = root; if (r.n == 2 * T - 1) ( Node s = new Node(); root = s; s.leaf = false; s.n = 0; s.child(0) = r; Split(s, 0, r); insertValue(s, key); ) else ( insertValue(r, key); ) ) // Insert the node final private void insertValue(Node x, int k) ( if (x.leaf) ( int i = 0; for (i = x.n - 1; i>= 0 && k  = 0 && k x.key(i)) ( i++; ) ) insertValue(x.child(i), k); ) ) public void Show() ( Show(root); ) // Display private void Show(Node x) ( assert (x == null); for (int i = 0; i < x.n; i++) ( System.out.print(x.key(i) + " "); ) if (!x.leaf) ( for (int i = 0; i < x.n + 1; i++) ( Show(x.child(i)); ) ) ) // Check if present public boolean Contain(int k) ( if (this.Search(root, k) != null) ( return true; ) else ( return false; ) ) public static void main(String() args) ( BTree b = new BTree(3); b.Insert(8); b.Insert(9); b.Insert(10); b.Insert(11); b.Insert(15); b.Insert(20); b.Insert(17); b.Show(); if (b.Contain(12)) ( System.out.println("found"); ) else ( System.out.println("not found"); ) ; ) ) 
// Searching a key on a B-tree in C #include #include #define MAX 3 #define MIN 2 struct BTreeNode ( int val(MAX + 1), count; struct BTreeNode *link(MAX + 1); ); struct BTreeNode *root; // Create a node struct BTreeNode *createNode(int val, struct BTreeNode *child) ( struct BTreeNode *newNode; newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode)); newNode->val(1) = val; newNode->count = 1; newNode->link(0) = root; newNode->link(1) = child; return newNode; ) // Insert node void insertNode(int val, int pos, struct BTreeNode *node, struct BTreeNode *child) ( int j = node->count; while (j> pos) ( node->val(j + 1) = node->val(j); node->link(j + 1) = node->link(j); j--; ) node->val(j + 1) = val; node->link(j + 1) = child; node->count++; ) // Split node void splitNode(int val, int *pval, int pos, struct BTreeNode *node, struct BTreeNode *child, struct BTreeNode **newNode) ( int median, j; if (pos> MIN) median = MIN + 1; else median = MIN; *newNode = (struct BTreeNode *)malloc(sizeof(struct BTreeNode)); j = median + 1; while (j val(j - median) = node->val(j); (*newNode)->link(j - median) = node->link(j); j++; ) node->count = median; (*newNode)->count = MAX - median; if (pos val(node->count); (*newNode)->link(0) = node->link(node->count); node->count--; ) // Set the value int setValue(int val, int *pval, struct BTreeNode *node, struct BTreeNode **child) ( int pos; if (!node) ( *pval = val; *child = NULL; return 1; ) if (val val(1)) ( pos = 0; ) else ( for (pos = node->count; (val val(pos) && pos> 1); pos--) ; if (val == node->val(pos)) ( printf("Duplicates are not permitted"); return 0; ) ) if (setValue(val, pval, node->link(pos), child)) ( if (node->count < MAX) ( insertNode(*pval, pos, node, *child); ) else ( splitNode(*pval, pval, pos, node, *child, child); return 1; ) ) return 0; ) // Insert the value void insert(int val) ( int flag, i; struct BTreeNode *child; flag = setValue(val, &i, root, &child); if (flag) root = createNode(i, child); ) // Search node void search(int val, int *pos, struct BTreeNode *myNode) ( if (!myNode) ( return; ) if (val val(1)) ( *pos = 0; ) else ( for (*pos = myNode->count; (val val(*pos) && *pos> 1); (*pos)--) ; if (val == myNode->val(*pos)) ( printf("%d is found", val); return; ) ) search(val, pos, myNode->link(*pos)); return; ) // Traverse then nodes void traversal(struct BTreeNode *myNode) ( int i; if (myNode) ( for (i = 0; i count; i++) ( traversal(myNode->link(i)); printf("%d ", myNode->val(i + 1)); ) traversal(myNode->link(i)); ) ) int main() ( int val, ch; insert(8); insert(9); insert(10); insert(11); insert(15); insert(16); insert(17); insert(18); insert(20); insert(23); traversal(root); printf(""); search(11, &ch, root); )
// Searching a key on a B-tree in C++ #include using namespace std; class TreeNode ( int *keys; int t; TreeNode **C; int n; bool leaf; public: TreeNode(int temp, bool bool_leaf); void insertNonFull(int k); void splitChild(int i, TreeNode *y); void traverse(); TreeNode *search(int k); friend class BTree; ); class BTree ( TreeNode *root; int t; public: BTree(int temp) ( root = NULL; t = temp; ) void traverse() ( if (root != NULL) root->traverse(); ) TreeNode *search(int k) ( return (root == NULL) ? NULL : root->search(k); ) void insert(int k); ); TreeNode::TreeNode(int t1, bool leaf1) ( t = t1; leaf = leaf1; keys = new int(2 * t - 1); C = new TreeNode *(2 * t); n = 0; ) void TreeNode::traverse() ( int i; for (i = 0; i traverse(); cout << " " 
 search(k); ) void BTree::insert(int k) ( if (root == NULL) ( root = new TreeNode(t, true); root->keys(0) = k; root->n = 1; ) else ( if (root->n == 2 * t - 1) ( TreeNode *s = new TreeNode(t, false); s->C(0) = root; s->splitChild(0, root); int i = 0; if (s->keys(0) C(i)->insertNonFull(k); root = s; ) else root->insertNonFull(k); ) ) void TreeNode::insertNonFull(int k) ( int i = n - 1; if (leaf == true) ( while (i>= 0 && keys(i)> k) ( keys(i + 1) = keys(i); i--; ) keys(i + 1) = k; n = n + 1; ) else ( while (i>= 0 && keys(i)> k) i--; if (C(i + 1)->n == 2 * t - 1) ( splitChild(i + 1, C(i + 1)); if (keys(i + 1) insertNonFull(k); ) ) void TreeNode::splitChild(int i, TreeNode *y) ( TreeNode *z = new TreeNode(y->t, y->leaf); z->n = t - 1; for (int j = 0; j keys(j) = y->keys(j + t); if (y->leaf == false) ( for (int j = 0; j C(j) = y->C(j + t); ) y->n = t - 1; for (int j = n; j>= i + 1; j--) C(j + 1) = C(j); C(i + 1) = z; for (int j = n - 1; j>= i; j--) keys(j + 1) = keys(j); keys(i) = y->keys(t - 1); n = n + 1; ) int main() ( BTree t(3); t.insert(8); t.insert(9); t.insert(10); t.insert(11); t.insert(15); t.insert(16); t.insert(17); t.insert(18); t.insert(20); t.insert(23); cout << "The B-tree is: "; t.traverse(); int k = 10; (t.search(k) != NULL) ? cout << endl << k << " is found" : cout << endl << k << " is not Found"; k = 2; (t.search(k) != NULL) ? cout << endl << k << " is found" : cout << endl << k << " is not Found"; ) 

Complexiteit zoeken op B Tree

In het ergste geval Tijdscomplexiteit: Θ(log n)

Gemiddelde casus Tijdscomplexiteit: Θ(log n)

In het beste geval Tijdscomplexiteit: Θ(log n)

Gemiddelde complexiteit van casusruimte: Θ(n)

In het ergste geval Ruimtecomplexiteit: Θ(n)

B Tree-toepassingen

  • databases en bestandssystemen
  • om gegevensblokken op te slaan (secundaire opslagmedia)
  • multilevel indexering

Interessante artikelen...