#include <iostream> using namespace std; template <class K,int M> struct BTreeNode { K _keys[M]; BTreeNode* _subs[M + 1]; BTreeNode* _parent; size_t _size; BTreeNode(const K& key) :_parent(NULL) , _size(0) { for (int i = 0; i < M; ++i) { _keys[i] = 0; } for (int i = 0; i <= M; ++i) { _subs[i] = NULL; } _keys[_size++] = key; } ~BTreeNode(){}; }; template <class K,int M> class BTree { public: typedef BTreeNode<K, M> Node; BTree() :_root(NULL) {} pair<Node*, int> Find(const K& key) { if (_root == NULL) { return pair<Node*, int>(NULL, -1); } Node* prev = NULL; Node* cur = _root; while (cur) { int i = 0; for (; i < (int)cur->_size; ) { if (key>cur->_keys[i]) ++i; else if (key < cur->_keys[i]){ break; } else return pair<Node*, int>(cur, i); } prev = cur; cur = cur->_subs[i]; } return pair<Node*, int>(prev, -1); } bool Insert(const K& key) { if (_root == NULL) { _root = new Node(key); return true; } pair<Node*, int> ret = Find(key); if (ret.second != -1) return false; Node* cur = ret.first; Node* prev = NULL; int i = cur->_size; while (i > ret.second&&key<cur->_keys[i-1]) { cur->_keys[i ] = cur->_keys[i-1]; --i; } cur->_keys[i] = key; ++cur->_size; if (cur->_size < M) return true; int mid = M / 2; //K newKey = key; while (1){ Node* newNode = NULL; //cout << M << endl; while (mid < M - 1) { if (newNode == NULL) newNode = new Node(cur->_keys[mid + 1]); else newNode->_keys[newNode->_size++] = cur->_keys[mid + 1]; cur->_keys[mid + 1] = 0; newNode->_subs[newNode->_size - 1] = cur->_subs[mid+1]; if (cur->_subs[mid+1]) (cur->_subs[mid+1])->_parent = newNode; cur->_subs[++mid] = NULL; newNode->_subs[newNode->_size] = cur->_subs[mid+1];; if (cur->_subs[mid+1]) (cur->_subs[mid+1])->_parent = newNode; cur->_subs[mid+1] = NULL; --cur->_size; } //cur->_subs[M / 2 + 1] = newNode; prev = cur->_parent; if (prev == NULL) { prev = new Node(cur->_keys[M / 2]); cur->_keys[M / 2] = 0; prev->_subs[0] = cur; prev->_subs[1] = newNode; cur->_parent = prev; newNode->_parent = prev; --cur->_size; _root = prev; return true; } i = prev->_size - 1; while (i >= 0 && prev->_keys[i] > cur->_keys[M / 2]) { prev->_keys[i + 1] = prev->_keys[i]; prev->_subs[i + 2] = prev->_subs[i+1]; --i; } prev->_keys[i + 1] = cur->_keys[M / 2]; prev->_subs[i + 2] = newNode; newNode->_parent = prev; cur->_subs[M / 2 + 1] = NULL; cur->_keys[M / 2] = 0; ++prev->_size; --cur->_size; cur = prev; prev = cur->_parent; mid = M / 2; if (cur->_size < M) return true; } return true; } bool Remove(const K& key) { if (_root == NULL) return false; pair<Node*, int> ret = Find(key); if (ret.second == -1) return false; Node* cur = ret.first; Node* prev = NULL; int index = ret.second; int pindex = 0; K newKey = key; while (cur) { prev = cur->_parent;//获取父节点 if (cur->_subs[index] == NULL)//叶子节点 { if (cur->_size >= M / 2){//节点key 数量 >= M/2,直接删除 for (int i = index; i < (int)cur->_size; ++i) { cur->_keys[i] = cur->_keys[i + 1]; } cur->_size--; return true; } if (prev == NULL)//父为空 只有一个节点 { if (cur->_size == 1)//只有一个key 删除后 释放节点 _root制空 { _root = NULL; delete cur; } else//否则删除 key 移动其他 { for (int i = index; i < (int)cur->_size; ++i) { cur->_keys[i] = cur->_keys[i + 1]; } } return true; } else//父不为空 { int dev = 0; for (; dev <= (int)prev->_size; ++dev)//判断删除操作的节点在父节点的关键字的位置(0--m-1) { if (prev->_subs[dev] == cur) break; } if (dev !=0 && (int)prev->_subs[dev - 1]->_size > M / 2)//cur不为prev最左sub 找左边替代 { Node* tmp = prev->_subs[dev - 1]; cur->_keys[index] = prev->_keys[dev - 1]; prev->_keys[dev - 1] = tmp->_keys[tmp->_size-1]; tmp->_keys[tmp->_size - 1] = 0; tmp->_size--; return true; } if (dev != (int)prev->_size && (int)(prev->_subs[dev + 1]->_size) > M / 2)//不为最右 找右替代 { Node* tmp = prev->_subs[dev + 1]; cur->_keys[index] = prev->_keys[dev ]; prev->_keys[dev ] = tmp->_keys[0]; tmp->_keys[tmp->_size - 1] = 0; for (int i = 0; i <(int) tmp->_size; ++i) { tmp->_keys[i] = tmp->_keys[i + 1]; } tmp->_size--; return true; } for (int i = index; i < (int)cur->_size; ++i) { cur->_keys[i] = cur->_keys[i + 1]; } cur->_size--; //需要合并 Node* ppNode = NULL; while (1){ if (dev != 0) { ppNode = prev->_parent; Node* sub = prev->_subs[dev - 1]; sub->_keys[sub->_size++] = prev->_keys[dev - 1]; for (int i = 0; i <(int)cur->_size;++i) { sub->_keys[sub->_size++] = cur->_keys[i]; } for (int i = dev - 1; i < (int)prev->_size; ++i) { prev->_keys[i] = prev->_keys[i + 1]; prev->_subs[i + 1] = prev->_subs[i + 2]; } if (sub->_subs[0] == NULL){ delete cur; } else { sub->_subs[sub->_size] = cur; cur->_parent = sub; } if ((int)prev->_size-- >1) return true; else { if (ppNode==NULL) { _root = sub; sub->_parent = NULL; delete prev; return true; } else { sub->_parent = prev->_parent; memcpy(prev, sub, sizeof(Node)); delete sub; cur = prev; prev = ppNode; for (dev=0; dev <= (int)prev->_size; ++dev)//判断删除操作的节点在父节点的关键字的位置(0--m-1) { if (prev->_subs[dev] == cur) break; } return true; } } } else { ppNode = prev->_parent; Node* sub = prev->_subs[dev +1]; cur->_keys[cur->_size++] = prev->_keys[dev]; for (int i = 0; i <(int)sub->_size;++i) { cur->_keys[cur->_size++] = sub->_keys[i]; } for (int i = dev ; i < (int)prev->_size; ++i) { prev->_keys[i] = prev->_keys[i + 1]; prev->_subs[i + 1] = prev->_subs[i + 2]; } if (cur->_subs[0] == NULL){ delete sub; } else { cur->_subs[cur->_size] = sub; sub->_parent = cur; } if ((int)prev->_size-- >1) return true; else { if (ppNode == NULL) { _root = cur; cur->_parent = NULL; delete prev; return true; } else { cur->_parent = prev->_parent; memcpy(prev, cur, sizeof(Node)); delete cur; cur = prev; prev = ppNode; for (dev = 0; dev <= (int)prev->_size; ++dev)//判断删除操作的节点在父节点的关键字的位置(0--m-1) { if (prev->_subs[dev] == cur) break; } return true; } } } } } } else//不为叶子 { if (cur->_subs[index + 1]->_size >0)//找右孩子最小替代删除 { Node* sub = cur->_subs[index + 1]; while (sub->_subs[0]) { sub = sub->_subs[0]; } cur->_keys[index] = sub->_keys[0]; cur = sub; index = 0; } else if (cur->_subs[index]->_size >0)//找左孩子最大替代 { Node* sub = cur->_subs[index]; int size=sub->_size; while (sub->_subs[0]){ size = sub->_size; sub = sub->_subs[size]; } cur->_keys[index] = sub->_keys[size - 1]; cur = sub; index = (int)sub->_size; } else { delete cur->_subs[index]; delete cur->_subs[index + 1]; cur->_subs[index] = NULL; cur->_subs[index] = NULL; } } } return true; } void Traverse() { _Traverse(_root); cout << endl; } private: void _Traverse(Node* root) { if (root == NULL) return; int i = 0; for (; i <(int) root->_size; ++i) { if (i == 0) _Traverse(root->_subs[0]); cout << root->_keys[i]<<" "; _Traverse(root->_subs[i+1]); } } Node* _root; };
c++ B-Tree的操作
原创
©著作权归作者所有:来自51CTO博客作者霜柒染的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:c++ 红黑树的插入
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【索引的数据结构】第1章节:B+Tree存储结构
B+Tree的数据结构
存储引擎 数据结构 MySQL B+Tree -
BTree B+Tree
etails/7786014 B-TreeT度的B树,满足以下条件:每个节点至多有2T个节点除根节点外,其他每个分支节点至少有T子树根节点至少有两颗子树所有的叶子节点在...
BTree B+Tree 子节点 子树 .net -
什么是B+Tree
B+Tree的介绍
子节点 数据 链表 数据库 spring -
MySQL索引一(B+Tree)
B+Tree索引,索引选择性
B+Tree索引