标签:btree
B树的性质:
根节点至少有两个孩子
每个非根节点有[,M]个孩子
每个非根节点有[-1,M-1]个关键字,并且以升序排列
key[i]和key[i+1]之间的孩子节点的值介于key[i]、key[i+1]之间
所有的叶子节点都在同一层
以下代码实现了B树的查找和插入操作,删除操作暂未实现
插入:先找到插入结点的位置,插入后判断关键字的个数是否小于M(M为阶数),小于返回,不小于进行分裂。
删除:任一关键字K的中序前趋(后继)必是K的左子树(右子树)中最右(左)下的结点中最后(最前)一个关键字。
BTree.h
#pragma once #include <iostream> template<class K,int M> struct BTreeNode { K _keys[M]; BTreeNode* _subs[M+1]; BTreeNode* _parents; size_t _size; BTreeNode() : _parents(NULL) , _size(0) { int i = 0; for (; i < M; ++i){ _keys[i] = 0; _subs[i] = NULL; } } }; template<class K,int M> class BTree { typedef BTreeNode<K, M> Node, *Node_P; public: BTree() :_root(NULL) {} ~BTree() {} public: std::pair<Node_P, int> Find(const K& key) { if (_root == NULL) return std::pair<Node_P, int >(NULL,-1); Node_P cur = _root; Node_P parent = NULL; while (cur){ size_t i = 0; while (i < cur->_size){ if (key == cur->_keys[i]){ return std::pair<Node_P, int >(cur, i); } else if (key > cur->_keys[i]){ i++; } else break; } parent = cur; cur = cur->_subs[i]; } return std::pair<Node_P, int >(parent, -1); } bool Insert(const K& key) { if (_root == NULL){ _root = new Node; _root->_keys[0] = key; _root->_size++; return true; } std::pair<Node_P, int > res = Find(key); if (res.second != -1) return false; K newkey = key; Node_P cur = res.first; Node_P sub = NULL; while (1){ int res_index = _Insert(cur, newkey); cur->_subs[res_index + 1] = sub; //满足规则,关键字个数小于M if (cur->_size < M) return true; //不满足,进行分裂 Node_P tmp = new Node; sub = tmp; size_t div = (cur->_size - 1) / 2; //中位数 //size_t div = MidNum(cur);//快排的方法求中位数 size_t i = div + 1; size_t index = 0; while (i < cur->_size){ tmp->_keys[index] = cur->_keys[i]; tmp->_subs[index] = cur->_subs[i]; cur->_keys[i] = K(); cur->_subs[i] = NULL; tmp->_size++; cur->_size--; index++; i++; } tmp->_subs[index] = cur->_subs[i]; cur->_subs[i] = NULL; newkey = cur->_keys[div]; cur->_keys[div] = K (); cur->_size--; cur = cur->_parents; if (cur == NULL){ cur = new Node; cur->_keys[0] = newkey; cur->_size++; cur->_subs[1] = sub; sub->_parents = cur; cur->_subs[0] = _root; _root->_parents = cur; _root = cur; break; } else{ sub->_parents = cur; } } } //任一关键字K的中序前趋(后继)必是K的左子树(右子树)中最右(左)下的结点中最后(最前)一个关键字。 //bool Remove(K& key); void InOrder() { _InOrder(_root); std::cout << std::endl; } private: int _Insert(Node_P& cur, K &key) { int end = cur->_size - 1; while (end >= 0){ if (cur->_keys[end] > key){ cur->_keys[end + 1] = cur->_keys[end]; cur->_subs[end + 2] = cur->_subs[end+1];//孩子节点跟着移动 end--; } else break; } cur->_keys[end + 1] = key; cur->_size++; return end + 1; } void _InOrder(Node_P root) { if (root == NULL) return; int i = 0; for (; i < root->_size; ++i){ _InOrder(root->_subs[i]); std::cout << root->_keys[i]<<" "; } _InOrder(root->_subs[i]); } private: Node_P _root; }; void Test1() { BTree<int,3> b; int a[7]={53, 75, 139, 49, 145, 36, 101}; for (int i = 0; i < sizeof(a) / sizeof(a[0]); ++i) { b.Insert(a[i]); } b.InOrder(); }
BTree.cpp
#include "BTree.h" int main() { Test1(); return 0; }
《完》
本文出自 “零蛋蛋” 博客,谢绝转载!
标签:btree
原文地址:http://lingdandan.blog.51cto.com/10697032/1828742