【数据结构】B树的详解

来源:互联网 发布:centos 下载 编辑:程序博客网 时间:2024/06/05 16:22

B树的定义:

B 树是为了磁盘或其它存储设备而设计的一种多叉(下面你会看到,相对于二叉,B树每个内结点有多个分支,即多叉)平衡查找树。
B 树又叫平衡多路查找树。一棵m阶的B 树 (m叉树)的特性如下:树中每个结点最多含有m个孩子(m>=2);除根结点和叶子结点外,其它每个结点至少有[ceil(m / 2)]个孩子(其中ceil(x)是一个取上限的函数);若根结点不是叶子结点,则至少有2个孩子(特殊情况:没有孩子的根结点,即根结点为叶子结点,整棵树只有一个根节点);所有叶子结点都出现在同一层,叶子结点不包含任何关键字信息(可以看做是外部接点或查询失败的接点,实际上这些结点不存在,指向这些结点的指针都为null);每个非终端结点中包含有n个关键字信息: (n,P0,K1,P1,K2,P2,......,Kn,Pn)。其中:
       a)   Ki (i=1...n)为关键字,且关键字按顺序升序排序K(i-1)< Ki。 
       b)   Pi为指向子树根的接点,且指针P(i-1)指向子树种所有结点的关键字均小于Ki,但都大于K(i-1)。 
       c)   关键字的个数n必须满足: [ceil(m / 2)-1]<= n <= m-1。

B数的代码实现:

#include<iostream>using namespace std;#include<assert.h>template<class K,size_t M = 3>struct BTreeNode{K _keys[M];BTreeNode<K, M> *_subs[M+1];BTreeNode<K, M> *_parent;size_t _size;//表示存储了多少个key值BTreeNode():_size(0), _parent(NULL){memset(_subs, 0, sizeof(_subs));_parent = NULL;_size = 0;/*for (size_t i = 0; i <= M; ++i){_subs[i] = NULL;}*/}};template<class K,class V,size_t M=3>class BTree{typedef BTreeNode<K, M> Node;public:BTree():_root(NULL){}pair<Node*, int> Find(const K& key)//查找一个数字{Node* parent = NULL;Node* cur = _root;while (cur){size_t i = 0;for (; i < cur->_size;){if (cur->_keys[i] < key){++i;}else if (cur->_keys[i]>key){break;}else{return make_pair(cur, i);}}parent = cur;cur = cur->_subs[i];}return make_pair(parent, -1);}bool Insert(const K& key){if (_root == NULL){_root = new Node;_root->_keys[0] = key;_root->_size = 1;return true;}pair<Node*, int> ret = Find(key);if (ret.second >= 0){return false;}Node* cur = ret.first;K newKey = key;Node* sub = NULL;while (1){InsertKey(cur, sub, newKey);if (cur->_size < M){return true;}//不满足规则分裂Node* newNode = new Node;size_t mid = M / 2;size_t i = mid + 1;size_t index = 0;for (; i < cur->_size; ++i){newNode->_keys[index] = cur->_keys[i];newNode->_subs[index] = cur->_subs[i];++index;newNode->_size++;if (cur->_subs[i]){Node* sub = cur->_subs[i];cur->_subs[i] = NULL;sub->_parent = newNode;}}newNode->_subs[index] = cur->_subs[i];if (cur->_subs[i]){Node* sub = cur->_subs[i];cur->_subs[i] = NULL;sub->_parent = newNode;}cur->_size = (cur->_size) - (newNode->_size) - 1;if (cur->_parent == NULL){_root = new Node;_root->_keys[0] = cur->_keys[mid];_root->_subs[0] = cur;cur->_parent = _root;_root->_subs[1] = newNode;newNode->_parent = _root;_root->_size++;return true;}else{newKey = cur->_keys[mid];cur = cur->_parent;sub = newNode;}}}void InsertKey(Node* cur, Node* sub, const K& key){assert(cur);int end = (cur->_size) - 1;for (; end >= 0; --end){if (cur->_keys[end] < key){break;}else{cur->_keys[end + 1] = cur->_keys[end];cur->_subs[end + 2] = cur->_subs[end + 1];}}cur->_keys[end + 1] = key;cur->_subs[end + 2] = sub;if (sub){sub->_parent = cur;}cur->_size++;}void InOrder(){_InOrder(_root);cout << endl;}protected:void _InOrder(Node* root){if (root == NULL){return;}size_t i = 0;for (; i < root->_size; ++i){_InOrder(root->_subs[i]);cout << root->_keys[i] << " ";}_InOrder(root->_subs[i]);}protected:Node* _root;};void TestBTree(){BTree<int, int> t;int a[] = { 34, 67, 88, 32, 90, 25, 19 };cout << "插入后:" << "";for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i){t.Insert(a[i]);}t.InOrder();}int main(){TestBTree();system("pause");return 0;}
B树运行的结果:



0 0
原创粉丝点击