#include #include #include #include using namespace std; const int m = 2; // B-tree of order m const int a = m; // minimal number of keys const int b = 2*m; // maximal number of keys template struct Node { // data vector keys; vector children; Node* parent; // interface Node (Node* p) {parent = p;} bool is_leaf() {return children.size()==0;} Node* root () { return (parent==0) ? this : parent->root(); } Node* find_node (T item); int find_pos (T item); bool equals_item (int pos, T item); } ; // finds first position i such that keys[i]>=item template int Node::find_pos (T item) { int i = 0; while ((i bool Node::equals_item (int pos, T item) { return (pos Node* Node::find_node (T item) { if (is_leaf()) return this; int pos = find_pos(item); if (equals_item(pos, item)) return this; else return children[pos]->find_node(item); } template VEC subseq (VEC vec, int start, int end) { int size = (vec.size()==0) ? 0 : end-start; VEC result(size); for (int i = 0; i Node* balance (Node* node) { int n = node->keys.size(); if (n<=b) return 0; T median = node->keys[a]; // create a new node Node* node2 = new Node(node->parent); node2->keys = subseq(node->keys, a+1, node->keys.size()); node2->children = subseq(node->children, a+1, node->children.size()); for (int i=0; ichildren.size(); i++) node2->children[i]->parent = node2; // handle node node->keys = subseq(node->keys, 0, a); node->children = subseq(node->children, 0, a+1); Node* parent = node->parent; if (parent==0) // split the root! { Node* root = new Node(0); root->keys.push_back(median); root->children.push_back(node); root->children.push_back(node2); node->parent = root; node2->parent = root; return root; } // otherwise: insert in parent int pos=0; while (parent->children[pos]!=node) pos++; parent->keys.insert(parent->keys.begin()+pos, median); parent->children.insert(parent->children.begin()+pos+1, node2); // recursive call; return balance(parent); } template void show (Node *node) { cout << node << ": "; if (node->children.size()>0) { cout << node->children[0]; for (int i=0; ikeys.size(); i++) cout << " |" << node->keys[i] << "| " << node->children[i+1]; } else for (int i=0; ikeys.size(); i++) cout << node->keys[i] << " "; cout << endl; for (int i=0; ichildren.size(); i++) show(node->children[i]); } // we could work with a root pointer, but for later use it is // better to wrap it into a class template class abTree { public: abTree () {root = new Node(0);} void insert (T item); bool find (T item); void show () { ::show(root); } private: Node *root; }; template void abTree::insert (T item) { Node* node = root->find_node(item); int i=node->find_pos(item); if (node->equals_item(i,item)) node->keys[i] = item; else { node->keys.insert(node->keys.begin()+i, item); Node* new_root = balance(node); if (new_root) root = new_root; } } template bool abTree::find (T item) { Node* node = root->find_node(item); int i=node->find_pos(item); return node->equals_item(i, item); } int main () { abTree tree; // insertion demo for (int i=0; i<5; i++) { tree.insert(i); tree.show(); } // testing insertion and retrieval int n = 10; for (int i=0; i set; set set; // should be faster int nn = 1000000; for (int i=0; i