English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Definition
In computer science, B-tree (English: B-tree) is a self-balancing tree that can maintain data in order. This data structure allows the operations of searching for data, sequential access, inserting data, and deleting data to be completed in logarithmic time.
Why introduce B-tree63;
Firstly, including the red-black tree we introduced earlier, input is stored intomemoryainternal search tree。
B-tree is an extension of the previous balanced tree algorithm, which supports storingdisk or networksymbol tableExternal lookupThese files may be much larger than the input we have considered before (difficult to store in memory).
Since the content is stored on disk, it will naturally cause disk I/Frequent read and write operations (disk read and write speeds are limited) can lead to low query efficiency.
Therefore, reducing the depth of the tree is naturally very important. Therefore, we introduce the B-tree, a multi-way search tree.
characteristics
Each node in the tree can have at most m children (m>=2);
Except for the root and leaf nodes, each node has at least [ceil(m / 2children (where ceil(x) is an upper bound function);
If the root node is not a leaf node, then there are at least2children (special case: the root node has no children, i.e., the root node is a leaf node, and the entire tree has only one root node);
All leaf nodes appear on the same level (the lowest level),Leaf nodes are external nodes, which store content, i.e., key and value。
Other nodes are internal nodes, which store indexes, i.e., key and next。
key of internal node: K[1], K[2], ..., K[M-1]; and K[i] < K[i+1];
pointer to content node next: P[1], P[2], ..., P[M]; where P[1], K[i] less than K[1], K[i] subtree, P[M] points to keywords greater than K[M-1], K[i] belongs to (K[i-1], K[i]) subtree;
For example: (M=3)
search and insert
For convenience, a special sentinel key is used here, which is less than all other keys, using*means.
Initially, the B-tree contains only one root node, and the root node only contains the sentinel key at initialization.
Each key in the internal nodes is associated with a node, and the subtree rooted at this node, where all keys are greater than or equal to the key associated with this node, but less than all other keys.
These conventions can greatly simplify the code.
code
Click to download.
This code implementation introduces sentinel keys, but they are excluded from the output.
The B-tree containing sentinel keys in the code (save the image locally to see the text more clearly):
The B-tree output by the code (save the image locally to see the text more clearly):
public class BTree<Key extends Comparable<Key>, Value> { // max children per B-tree node = M-1 // (must be even and greater than 2) private static final int M = 4; private Node root; // root of the B-tree private int height; // height of the B-tree private int n; // number of key-value pairs in the B-tree // helper B-tree node data type private static final class Node { private int m; // number of children private Entry[] children = new Entry[M]; // the array of children // create a node with k children private Node(int k) { m = k; } } // internal nodes: only use key and next // external nodes: only use key and value private static class Entry { private Comparable key; private Object val; private Node next; // helper field to iterate over array entries public Entry(Comparable key, Object val, Node next) { this.key = key; this.val = val; this.next = next; } } /** * Initializes an empty B-tree. */ public BTree() { root = new Node(0); } /** * Returns true if this symbol table is empty. * @return {@code true} if this symbol table is empty; {@code false} otherwise */ public boolean isEmpty() { return size() == 0; } /** * Returns the number of key-value pairs in this symbol table. * @return the number of key-value pairs in this symbol table */ public int size() { return n; } /** * Returns the height of this B-tree (for debugging). * * @return the height of this B-tree */ public int height() { return height; } /** * Returns the value associated with the given key. * * @param key the key * @return the value associated with the given key if the key is in the symbol table * and null if the key is not in the symbol table * @throws NullPointerException if key is null */ public Value get(Key key) { if (key == null) { throw new NullPointerException("key must not be null"); } return search(root, key, height); } @SuppressWarnings("unchecked") private Value search(Node x, Key key, int ht) { Entry[] children = x.children; // external node to the bottommost leaf node, traverse if (ht == 0) { for (int j = 0; j < x.m; j++) { if (eq(key, children[j].key)) { return (Value) children[j].val; } } } // internal node recursively searches the next address else { for (int j = 0; j < x.m; j++) { if (j+1 == x.m || less(key, children[j+1].key)) { return search(children[j].next, key, ht-1); } } } return null; } /** * Inserts the key-value pair into the symbol table, overwriting the old value * with the new value if the key is already in the symbol table. * If the value is null, this effectively deletes the key from the symbol table. * * @param key the key * @param val the value * @throws NullPointerException if key is null */ public void put(Key key, Value val) { if (key == null) { throw new NullPointerException("key must not be null"); } Node u = insert(root, key, val, height); //right node generated after splitting n++; if (u == null) { return; } // need to split root, reorganize root Node t = new Node(2); t.children[0] = new Entry(root.children[0].key, null, root); t.children[1] = new Entry(u.children[0].key, null, u); root = t; height++; } private Node insert(Node h, Key key, Value val, int ht) { int j; Entry t = new Entry(key, val, null); // external node, also a leaf node, at the bottom of the tree, stores content value if (ht == 0) { for (j = 0; j < h.m; j++) { if (less(key, h.children[j].key)) { break; } } } // internal node, stores next address else { for (j = 0; j < h.m; j++) { if ((j+1 == h.m) || less(key, h.children[j+1].key)) { Node u = insert(h.children[j++].next, key, val, ht-1); if (u == null) { return null; } t.key = u.children[0].key; t.next = u; break; } } } for (int i = h.m; i > j; i--) { h.children[i] = h.children[i-1]; } h.children[j] = t; h.m++; if (h.m < M) { return null; } else { //Splitting node return split(h); } } // split node in half private Node split(Node h) { Node t = new Node(M/2); h.m = M/2; for (int j = 0; j < M/2; j++) { t.children[j] = h.children[M/2+j]; } return t; } /** * Returns a string representation of this B-tree (for debugging). * * @return a string representation of this B-tree. */ public String toString() { return toString(root, height, "") + "\n"; } private String toString(Node h, int ht, String indent) { StringBuilder s = new StringBuilder(); Entry[] children = h.children; if (ht == 0) { for (int j = 0; j < h.m; j++) { s.append(indent + children[j].key + " " + children[j].val + "\n"); } } else { for (int j = 0; j < h.m; j++) { if (j > 0) { s.append(indent + "(" + children[j].key + ))\n"); } s.append(toString(children[j].next, ht-1, indent + " ")); } } return s.toString(); } // comparison functions - make Comparable instead of Key to avoid casts private boolean less(Comparable k1, Comparable k2) { return k1.compareTo(k2) < 0; } private boolean eq(Comparable k1, Comparable k2) { return k1.compareTo(k2) == 0; } /** * Unit tests the {@code BTree} data type. * * @param args the command-line arguments */ public static void main(String[] args) { BTree<String, String> st = new BTree<String, String>(); st.put("www.cs.princeton.edu", "128.112.136.12 st.put("www.cs.princeton.edu", "128.112.136.11 st.put("www.princeton.edu", "128.112.128.15 st.put("www.yale.edu", ";130.132.143.21 st.put("www.simpsons.com", ";209.052.165.60); st.put("www.apple.com", ";17.112.152.32 st.put("www.amazon.com", ";207.171.182.16 st.put("www.ebay.com", ";66.135.192.87 st.put("www.cnn.com", ";64.236.16.20); st.put("www.google.com", ";216.239.41.99 st.put("www.nytimes.com", ";199.239.136.200); st.put("www.microsoft.com", ";207.126.99.140); st.put("www.dell.com", ";143.166.224.230); st.put("www.slashdot.org", ";66.35.250.151 st.put("www.espn.com", ";199.181.135.201 st.put("www.weather.com", ";63.111.66.11 st.put("www.yahoo.com", ";216.109.118.65 System.out.println("cs.princeton.edu: "); + st.get("www.cs.princeton.edu")); System.out.println("hardvardsucks.com: "); + st.get("www.harvardsucks.com")); System.out.println("simpsons.com: "); + st.get("www.simpsons.com")); System.out.println("apple.com: "); + st.get("www.apple.com")); System.out.println("ebay.com: "); + st.get("www.ebay.com")); System.out.println("dell.com: "); + st.get("www.dell.com")); System.out.println(); System.out.println("size: "); + st.size()); System.out.println("height: "); + st.height()); System.out.println(st); System.out.println(); } }
Output:
cs.princeton.edu: 128.112.136.12
hardvardsucks.com: null
simpsons.com: 209.052.165.60
apple.com: 17.112.152.32
ebay.com: 66.135.192.87
dell.com: 143.166.224.230
size: 17
height: 2
www.amazon.com 207.171.182.16
www.apple.com 17.112.152.32
www.cnn.com 64.236.16.20
(www.cs.princeton.edu)
www.cs.princeton.edu 128.112.136.12
www.cs.princeton.edu 128.112.136.11
www.dell.com 143.166.224.230
(www.ebay.com)
www.ebay.com 66.135.192.87
www.espn.com 199.181.135.201
www.google.com 216.239.41.99
(www.microsoft.com)
www.microsoft.com 207.126.99.140
www.nytimes.com 199.239.136.200
(www.princeton.edu)
www.princeton.edu 128.112.128.15
www.simpsons.com 209.052.165.60
(www.slashdot.org)
www.slashdot.org 66.35.250.151
www.weather.com 63.111.66.11
(www.yahoo.com)
www.yahoo.com 216.109.118.65
www.yale.edu 130.132.143.21
That's all for this article. Hope it helps everyone's learning and also hope everyone will support the Shouting Tutorial.
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been edited by humans, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (when sending an email, please replace # with @ to report, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.)