B树,B+树,B*树

第一个是B树,首先扩展一下Array

Array.prototype.center = function() {
	return Math.floor(this.length / 2);
}

Array.prototype.median = function() {
	return this.length > 0 ? this[this.center()] : null;
}

Array.prototype.first = function() {
	return this.length > 0 ? this[0] : null;
}

Array.prototype.last = function() {
	return this.length > 0 ? this[this.length-1] : null;
}

Array.prototype.findInsertPos = function(k) {
	if (this.length == 0) {
		return 0;
	}
	else if (k < this.first()) {
		return 0;
	}
	else if (k > this.last()) {
		return this.length;
	}
	else {
		for (var i=0; i<this.length-1; i++) {
			if ( k > this[i] && k < this[i+1]) {
				return i+1;
			}
		}
	}
	throw new Error();
	
}

Array.prototype.insert = function(k) {
	var p = this.findInsertPos(k);
	if (p >= this.length) this.push(k); else this.splice(p, 0, k);
}

定义Node节点

Node = function() {


	this.keys = new Array();
	this.children = new Array(); // store node // for root  ; for 2 | ceil(m / 2)  < num < M
	this.parent = null;


定义画布

<svg id="c" width="100%"  version="1.1" xmlns="http://www.w3.org/2000/svg" />

执行建立B树

	t = new Tree();
	t.init();
	t.b();
	t.display("c");	

建立B树

	this.b = function() {
		for (var i=0 ; i<data.length; i++) {
			var d = data[i];
			var p = this.findLeaf(d);
			this.root = p.addKey(this.root, d);
		}
	}


添加过程

	this.addKey = function(root, k) {
		this.keys.insert(k);
		
		if (this.keys.length > NUM) {
			root = this.split(root);
		}
		
		return root;
	}
	
	this.split = function(root) {
		var m = this.keys.median();
		var c = this.keys.center();

		var parent = this.parent;
		if (parent == null) {
			parent = new Node();
			root =parent;
			parent.children.push(this);
			this.parent = parent;
		}
		
		var la = this.keys.splice(0, c);
		var lc = this.children.splice(0, c+1);
		
		var l = new Node();
		l.keys = la;
		l.children = lc;
		for (var i=0; i<lc.length; i++) {
			lc[i].parent = l;
		}
		l.parent = parent;
		
		parent.addChild(m, l);
		root = this.parent.addKey(root, this.keys.shift());
		
		return root;

	}


显示如下图

F5


然后是B+树

定义Node节点

Node = function() {

	this.keys = new Array();
	this.children = new Array(); 
	this.parent = null;
	this.next = null;


建立B+树

	this.b1 = function() {

		for (var ij=0 ; ij<data.length; ij++) {
			var d = data[ij];
			var p = this.findLeaf(d);
			this.root = p.addKey(this.root, d);
		}
	}

添加节点过程

	this.update = function(n) {
		var p = this.children.indexOf(n);
		if (this.keys[p] > n.keys.first()) {
			this.keys[p] = n.keys.first();	
			if (this.parent != null) this.parent.update(this);
		}
	}

	this.addKey = function(root, k) {
		this.keys.insert(k);
		if (this.parent != null) this.parent.update(this);
		
		if (this.keys.length > NUM) {
			root = this.split(root);
		}
		
		return root;
	}
	
	this.split = function(root) {
		var m = this.keys.median();
		var c = this.keys.indexOf(m);

		var parent = this.parent;
		if (parent == null) {
			parent = new Node();
			root =parent;
			parent.children.push(this);
			this.parent = parent;
			parent.keys.push(this.keys.first());
		}
		
		var ra = this.keys.splice(c, this.keys.length - c);
		var rc = this.children.splice(c, this.children.length - c);
		
		var r = new Node();
		r.parent = parent;
		r.keys = ra;
		r.children = rc;
		for (var i=0; i<rc.length; i++) {
			rc[i].parent = r;
		}
		
		if (this.children.length == 0) {
			r.next = this.next;
			this.next = r;
		}
		
		var i = parent.keys.findInsertPos(m);
		parent.keys.splice(i,0,m);
		parent.children.splice(i,0,r);
		
		if (parent.keys.length > NUM) root = parent.split(root);
		
		return root;
	}

建立后显示下图


F5


然后是B*树

建立B*树

	this.b2 = function() {

		for (var ij=0 ; ij<data.length; ij++) {
			var d = data[ij];
			var p = this.findLeaf(d);
			this.root = p.addKey(this.root, d);
		}
	}

	this.findLeaf = function(k) {
		var p = this.root;
		while (p.children.length != 0) {
			var b = false;
			for (var i=p.keys.length-1; i>=0 ; i--) {
				if (k > p.keys[i]) {
					p = p.children[i];
					b = true;
					break ;
				}
			}
			if (b == false) p = p.children.first();
		}
		return p;
	}


添加节点过程

	this.update = function(n) {
		var p = this.children.indexOf(n);
		if (this.keys[p] > n.keys.first()) {
			this.keys[p] = n.keys.first();	
			if (this.parent != null) this.parent.update(this);
		}
	}

	this.addKey = function(root, k) {
		this.keys.insert(k);
		if (this.parent != null) this.parent.update(this);

		if (this.next != null && this.keys.length > NUM && this.next.keys.length < NUM ) {
			var k = this.keys.splice(this.keys.length-1, 1)[0];
			root = this.next.addKey(root, k);
		}
		else if (this.keys.length > NUM) {
			root = this.split(root);
		}
		
		return root;
	}
	
	this.split = function(root) {
		var m = this.keys.median();
		var c = this.keys.indexOf(m);

		var parent = this.parent;
		if (parent == null) {
			parent = new Node();
			root =parent;
			parent.children.push(this);
			this.parent = parent;
			parent.keys.push(this.keys.first());
		}
		
		var ra = this.keys.splice(c, this.keys.length - c);
		var rc = this.children.splice(c, this.children.length - c);
		
		var r = new Node();
		r.parent = parent;
		r.keys = ra;
		r.children = rc;
		for (var i=0; i<rc.length; i++) {
			rc[i].parent = r;
		}
		
		r.next = this.next;
		this.next = r;

		var i = parent.keys.findInsertPos(m);
		parent.keys.splice(i,0,m);
		parent.children.splice(i,0,r);
		
		if (parent.keys.length > NUM) root = parent.split(root);
		
		return root;
	}

显示下图

F5




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
B树是一种多路搜索,它是一种平衡的、自底向上构建的结构。B树又被称为平衡多路搜索,旨在减少存储访问时间。它的特点是每个节点可以包含多个子节点和关键字,并且节点中的关键字按照一定的顺序排列。B树还具有自平衡的特性,即当节点插入或删除后,仍然维持平衡状态。 B树的优点有: 1. 搜索效率高:B树的每个节点包含多个关键字和子节点,这使得在每一层的搜索过程中可以同时查找多个关键字,提高了搜索效率。 2. 存储空间利用率高:B树可以在一个节点中存储多个关键字,相比于二叉搜索,它的存储空间利用率更高。 3. 适合磁盘存储:由于B树节点的大小通常等于磁盘页面的大小,所以B树非常适合在磁盘上存储大量数据。 B*是在B树的基础上进行了优化的一种结构。它在B树的基础上增加了一些特性,使得B*的顺序访问更加高效。B*的特点是: 1. 非叶子节点的关键字数目可以达到M-1,叶子节点的关键字数目可以达到M/2-1,这样可以减少的高度。 2. 非叶子节点只有在关键字范围的最小值和最大值变化时才会更新,不会频繁增删节点。 B*相比于B树的优势在于: 1. 节点的利用率更高:B*中非叶子节点的关键字数目更多,可以更有效地利用节点的空间。 2. 查询效率更高:由于B*的高度比B树更低,所以查询的效率更高。 综上所述,B树和B*都是常用的结构,用来提高数据操作的效率,特别适合存储大量数据的场景,尤其对于磁盘存储更具优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值