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

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

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

  1. 根节点至少有两个孩子
  2. 每个非根节点有[M/2,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<iostream>
using namespace std;
template<class K,int M>
struct BTreeNode
{
	K  _keys[M];
	BTreeNode<K, M>* _subs[M + 1];
	BTreeNode<K, M>* _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<class K,class V,int M>
struct BTreeNodeKV
{
	pair<K, V> _kvs[M];
	BTreeNodeKV<K, V, M>* _subs[M + 1];
	BTreeNodeKV<K, V, M>* _parent;
	size_t _size;
};
template<class K,int M>
class BTree
{
	typedef BTreeNode<K, M> Node;
public:
	BTree()
		:_root(NULL)
	{}
	pair<Node*, int> Find(K& key)
	{
		if (_root == NULL)
			return pair<Node*, int>(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<Node*, int>(cur, i);
				else if (cur->_keys[i] < key)
				{
					++i;
				}
				else
					break;
			}
			parent = cur;
			cur = cur->_subs[i];
		}
		return pair<Node*, int>(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<Node*,int> 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<M)
						break;

					//分裂
					int div = M / 2;
					Node* sub = new Node;
					int index = 0;
					int i = div+1;
					while (i < M)
					{
						sub->_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<int, 3> 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<int, 3> 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;
}
时间: 2024-08-06 11:54:57

BTree---------详谈的相关文章

索引的分类--B-Tree索引和Hash索引

索引是存储引擎用来快速查找记录的一种数据结构,按照实现的方式有不同的种类,想B-Tree索引,hash索引,空间数据索引和全文索引等.下面主要说一下B-Tree索引和Hash索引.人们在谈论索引的时候如果没有特别说明,一般指的是B-Tree索引.B-Tree索引是使用B-Tree数据结构来存储索引的.B-Tree通常意味着所有的值是按照顺序存储的.B-Tree树有如下几个特征:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树:⑶除根结点之外的所有非终端结点至少有[m/2]

【Bitmap Index】B-Tree索引与Bitmap位图索引的锁代价比较研究

通过以下实验,来验证Bitmap位图索引较之普通的B-Tree索引锁的“高昂代价”.位图索引会带来“位图段级锁”,实际使用过程一定要充分了解不同索引带来的锁代价情况. 1.为比较区别,创建两种索引类型的测试表1)在表t_bitmap上创建位图索引[email protected]> create table t_bitmap (id number(10), name varchar2(10),sex varchar2(1)); Table created. [email protected]>

MySql索引算法原理解析(通俗易懂,只讲B-tree)

刚开始学习的时候,百度去查,但发现好多说得太复杂不好理解,结合各个文章总结一下(建议大概看文字,不理解不要紧,然后再看图的执行步骤然后在结合文字,这样一切就清晰好多) B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,大名鼎鼎的MySQL就普遍使用B+tree实现其索引结构. 那数据库为什么使用这种结构? 一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引

详谈何为404错误及404处理方法

404问题绝对关乎网站的优化,而大部分网站都会有404错误的相关处理,比如一个网站删除了页面内容,正常网站将自动返回404状态码,搜索引擎进行更新并删除,避免对网站用户及搜索引擎带来负面影响.但问题来了,如果网站只删除了内容,没有任何主体内容的页面被保存了下来,未做404处理.当然,存在一类网站只删除内容后返回正常200状态码,提醒一句"该内容已删除",但其都没有.可以发现目前这个搜藏中的url仍然正常返回200,http://cang.baidu.com/Lee/snap/3b0a0

mysql执行 sql文件遇到USING BTREE ) ENGINE=MyISAM DEFAULT CHARSET=utf8错误

使用navcat在导入别人发的mysql数据的时候,报了下面这个错误: [Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USING BTREE ) ENGINE=MyISAM DEFAULT CHARSET=utf8' at line 9 错误原因主要

自己写的java实现的多路搜索树 B-Tree

最近需要写范围查询的功能,最简单的应该是B+树吧,在了解B+树的时候,也看到了B-树.于是想先实现B-Tree再实现B+Tree,结果网上并没有找到B-Tree(多路搜索树),于是自己用java实现了一个,经过自己设计了很多测试用例,用Junit(临时学的)测试可用.在这里贴出来,希望能给初学者一点参考,也希望能有高人指点可以改进的地方,欢迎讨论批评指点!自己之前一直在做工程,这是一年多来首次写数据结构,自己还很弱,欢迎大家批评指正!!! 本B-Tree理论部分参考博客:http://blog.

btrfs(Btree FS)文件系统

Btrfs (Btree FS)文件系统:    是由Oracle(甲骨文)公司在2007年开发的一个写时复制(copy to write)文件系统,以解决文件系统中缺少池,快照,校验及跨多设备访问的一些问题而实现大规模化储存. Btrfs特点:    1.btrfs可由多个底层物理卷组成:支持RAID,以联机"添加."移除","修改"    2.写时复制更新机制(CoW):复制.更新及替换指针,而非"就地"更新:    3.扩展性:扩

B-Tree索引在sqlserver和mysql中的应用

在谈论数据库性能优化的时候,通常都会提到“索引”,但很多人其实并没有真正理解索引,也没有搞清楚索引为什么就能加快检索速度,以至于在实践中并不能很好的应用索引.事实上,索引是一种廉价而且十分有效的优化手段,设计优良的索引对查询性能提升确实能起到立竿见影的效果. 相信很多读者,都了解和使用过索引,可能也看过或者听过”新华字典“.”图书馆“之类比较通俗描述,但是对索引的存储结构和本质任然还比较迷茫. 有数据结构和算法基础的读者,应该都学过或者写过“顺序查找,二分查找(折半)查找,二叉树查找”这几种很经

B树、B-tree B+树、B*树

BST 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B-树(B树) 是一种多路搜索树(并不是二叉的): 1.定义任意非叶子结点最多只有M个儿子:且M>2: 2.根结点的儿子数为[2, M]: 3.除根结点以外的非叶子结点的儿子数为[M/2, M]: 4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字:(至少2个关键字) 5.非叶子结点的关键

&lt;摘录&gt;详谈高性能TCP服务器的开发

对于开发一款高性能服务器程序,广大服务器开发人员在一直为之奋斗和努力.其中一个影响服务器的重要瓶颈就是服务器的网络处理模块.如果一款服务器程序不能及时的处理用户的数据.则服务器的上层业务逻辑再高效也是徒劳.所以一个服务器程序的网络处理能力直接影响到整个服务器的性能, 本文主要介绍在windows平台下开发高性能的网络处理模块以及自己在设计开发服务器网络模块遇到的一些问题和开发心得.本篇主要介绍TCP服务器的设计, 下一篇将主要介绍UDP服务器的设计. 众所周知, 对于服务器来说windows下网