BTree---------详谈

一种适合外查找的树,它是一种平衡的多叉树,称为B树。

站在用户的角度思考问题,与客户深入沟通,找到梁园网站设计与梁园网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计、成都网站制作、企业官网、英文网站、手机端网站、网站推广、空间域名、虚拟主机、企业邮箱。业务覆盖梁园地区。

一棵M阶(M>2)的B树,是一棵平衡的M路平衡搜索树,可以是空树或者满足一下性质:

  1. 根节点至少有两个孩子

  2. 每个非根节点有[M/2BTree---------详谈,M]个孩子

  3. 每个非根节点有[M/2-1,M-1]个关键字,并且以升序排列

  4. key[i]和key[i+1]之间的孩子节点的值介于key[i]、key[i+1]之间

  5. 所有的叶子节点都在同一层

注:使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。按照翻译,B 通常认为是Balance的简称。这个数据结构一般用于数据库的索引,综合效率较高。

B-tree有以下特性:

1、关键字集合分布在整棵树中;

2、任何一个关键字出现且只出现在一个结点中;

3、搜索有可能在非叶子节点结束;

4、其搜索性能等价于在关键字全集内做一次二分查找;

5、自动层次控制;

鉴于B-tree具有良好的定位特性,其常被用于对检索时间要求苛刻的场合,例如:

1、B-tree索引是数据库中存取和查找文件(称为记录或键值)的一种方法。

2、硬盘中的结点也是B-tree结构的。与内存相比,硬盘必须花成倍的时间来存取一个数据元素,这是因为硬盘的机械部件读写数据的速度远远赶不上纯电子媒体的内存。与一个结点两个分支的二元树相比,B-tree利用多个分支(称为子树)的结点,减少获取记录时所经历的结点数,从而达到节省存取时间的目的。

#pragma once
#include
using namespace std;
template
struct BTreeNode
{
	K  _keys[M];
	BTreeNode* _subs[M + 1];
	BTreeNode* _parent;
	size_t _size;
	BTreeNode()
		:_parent(NULL)
		, _size(0)
	{
		for (int i = 0; i < M; ++i)
		{
			_keys[i] = K();
			_subs[i] = NULL;
		}
		_subs[M] = NULL;
	}
};//K
template
struct BTreeNodeKV
{
	pair _kvs[M];
	BTreeNodeKV* _subs[M + 1];
	BTreeNodeKV* _parent;
	size_t _size;
};
template
class BTree
{
	typedef BTreeNode Node;
public:
	BTree()
		:_root(NULL)
	{}
	pair Find(K& key)
	{
		if (_root == NULL)
			return pair(NULL, -1);
		Node* cur=_root;
		Node* parent = NULL;
		while (cur)
		{
			int size = cur->_size;
			int i;
			for (i = 0; i < size;)
			{
				if (cur->_keys[i] == key)
					return pair(cur, i);
				else if (cur->_keys[i] < key)
				{
					++i;
				}
				else
					break;
			}
			parent = cur;
			cur = cur->_subs[i];
		}
		return pair(parent, -1);
	}
	void _Insert(Node* cur,K& key, Node* sub)
	{
		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->_subs[end + 2] = sub;
		++cur->_size;
		if (sub)
			sub->_parent=cur;
	}
	bool Insert(K& key)
	{
		if (_root == NULL)
		{
			_root = new Node;
			_root->_keys[0] = key;
			_root->_size = 1;
			return true;
		}
		else
		{
			pair ret = Find(key);
			if (ret.second != -1)
				return false;
			else
			{
				Node* cur = ret.first;
				K newkey = key;
				Node* insert_sub = NULL;//第一次插入时insert_sub为NULL
				while (1)
				{
					_Insert(cur, newkey, insert_sub);
					if (cur->_size_keys[index] = cur->_keys[i];
						cur->_keys[i] = K();//还原为K类型的默认值
						sub->_subs[index] = cur->_subs[i];
						cur->_subs[i] = NULL;
						++index;
						++i;
						++sub->_size;
					}
					sub->_subs[index] = cur->_subs[i];
					cur->_subs[i - 1] = NULL;
					cur->_size -= (index+1);//减去右边和key的大小
					
					if (cur->_parent == NULL)
					{
						_root = new Node;
						_root->_keys[0] = cur->_keys[div];
						cur->_keys[div] = K();
						_root->_subs[0] = cur;
						cur->_parent = _root;
						_root->_subs[1] = sub;
						sub->_parent=_root;
						_root->_size = 1;
						return true;
					}
					else
					{
						insert_sub = sub;
						newkey = cur->_keys[div];
						cur = cur->_parent;
					}
				}
				return true;
			}
		}
	}
	void InOrder()
	{
		_InOrder(_root);
		cout << endl;
	}
protected:
	void _InOrder(Node* root)
	{
		if (root == NULL)
			return;
		int i = 0;
		for (i = 0; i < root->_size; ++i)
		{
			_InOrder(root->_subs[i]);
			cout << root->_keys[i] << " ";
		}
		_InOrder(root->_subs[i]);
	}
protected:
	Node* _root;
};
void Test1()
{
	//int arr[] = { 20, 30, 10 };
	/*BTree b;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
	{
		b.Insert(arr[i]);
	}*/
	int arr[] = { 53, 75, 139, 49, 145, 36, 101 };
	BTree b;
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
	{
		b.Insert(arr[i]);
	}
	b.InOrder();
}
#include"BTree.h"
int main()
{
	Test1();
	system("pause");
	return 0;
}




网站标题:BTree---------详谈
链接分享:http://scyanting.com/article/ijgijc.html