B树

B树操作与实现详解
本文详细介绍了B树的基本概念、关键属性以及核心操作代码,包括创建、搜索、分裂、非满节点处理和插入等。重点突出了B树在平衡搜索、磁盘应用中的优势,以及如何高效地在内存中实现这些操作。
关于B树就不废话了,具体书上有
#include <iostream>
#include <vector>
#define t 3
using namespace std;
class btreenode
{
	int  num;//键值的个数
	vector<btreenode*>  vptr;
	vector<int> key;
	bool leaf;
public:
	btreenode(){}//默认构造函数
	btreenode(int rnum,bool rleaf,vector<btreenode*> rvptr,vector<int> rkey):num(rnum),leaf(rleaf),vptr(rvptr)
	{
		int a;
		while(cin>>a)
		{
			key.push_back(a);
		}
	
	}
	friend btreenode* creat();
	friend void search(btreenode* nodex,int k);
	friend void split(btreenode* nodex,int i,btreenode* nodey);
	friend void nonfull(btreenode* nodex,int k);
	friend void insert(btreenode* root,int k);
	~btreenode()
	{
//		delete nodez;//同理
//		delete s;//只有确保new了该指针才可以使用delete的否则会造成一个错误。
//		delete p;//只有确保调用了的话才可以使用的,这里我们调用
	}
};
btreenode* creat()
{
	btreenode* p=new btreenode();//构造了一个空的节点,p指向该节点,由于我们的调用的默认的构造函数num为o,其他的为空
	p->leaf=true;
	return p;//这个指针是我们
}
void search(btreenode* nodex,int k)
{
	int i=1;
	while(i<nodex->num&&k<(nodex->key)[i])
	{
		++i;
	}
	if (i<nodex->num&&(nodex->key)[i]==k)
	{
		cout<<"we find the num k :"<<k<<" "<<"and the address is: "<<&(nodex->key)[i]<<endl;
	}
	if(nodex->leaf)
	{
		cout<<"this is null"<<endl;
	}
	else
		search((nodex->vptr[i]),k);
}
void split(btreenode* nodex,int i,btreenode* nodey)//如果是内节点的键值的个数是2*t-1就对于该节点执行如下的操作,假如要再次的插入
{
	btreenode* nodez=new btreenode();
	nodez->leaf=nodey->leaf;
	nodez->num=t-1;
	for(int a=1;a<=t-1;++a)
	{
		nodez->key[a]=nodey->key[a+t];//这里就凸显了使用容器vector的好处
	}
	if(!(nodey->leaf))
	{
		for(int j=1;j<=t;++j)
		{
			nodez->vptr[i]=nodey->vptr[i+t];
		}
	}
	nodey->num=t-1;
	for(int n=nodex->num+1;n>=i+1;--n)
	{
		nodex->vptr[n+1]=nodex->vptr[n];
	}
	for(int m=nodex->num;m>i;++m)
	{
		nodex->key[m+1]=nodex->key[m];
	}
	nodex->key[i]=nodey->key[t];
	nodex->vptr[i+1]=nodez;
	nodex->num=nodex->num+1;
	
}

void nonfull(btreenode* nodex,int k)//执行该操作,当是叶子节点以及非叶子节点进行的操作有如下的几种
{
	int i=nodex->num;
	if(nodex->leaf)
	{
		while (i>=1&& k<(nodex->key)[i])
		{
			nodex->key[i+1]=nodex->key[i];//使用容器的好处彰显了。c可以么?麻烦起来可以
			--i;
		}
		nodex->key[i+1]=k;
		nodex->num=nodex->num+1;
	}
	else//如果是非叶子节点的话,就需要向下进行探索了
	{
		while (i>=1&& k<nodex->key[i])
		{
			--i;
		}
		i=i+1;
		if((nodex->vptr[i])->num==2*t-1)
		{
			split(nodex,i,nodex->vptr[i]);
			if(k>nodex->key[i])
				++i;
		}
		nonfull(nodex->vptr[i],k);
		
	}
	
}
void insert(btreenode* root,int k)//只有在被操作的对象是一个叶子节点的时候才可以,其他的情况下要调用上面的nonfull()函数
{
	
	if(root->num==2*t-1)
	{
		btreenode* s=new btreenode();
		s->num=0;
		s->leaf=false;
		s->vptr[1]=root;
		split(s,1,root);
		nonfull(s,k);
	}
	else
		nonfull(root,k);
	
	}	

int main()
{
	int ra;
	int na;
	int rk;
	//这里有一个疑问就是对于那些new出来的东西,哪里有一个比较不错的处理方案呢?上面的话我们比不可少需要这么一个nodez之类的
	//去,在构造树的时候插入的话也不可以马上的在成员函数中delete啊,只有析构函数,但是对于很多的节点的话怎么去delete呢?
	//这里对于B树而言,添加键值以及指针有点麻烦。
	btreenode* nroot=new btreenode;  
	//上面的东西在这里的话是不是那么的特殊需要的,因为对于构造函数的话也是可以这么的构造一个对象,但是对于root的话,特殊点。
//	btreenode* nodea=creat();
	cin>>rk;
	insert(nroot,rk);//对于键值根假如有2*t-1的话插入一个键值,进行下面的操作。
	/

	return 0;
	

}

,属于平衡树,每一个节点的含有的键值以及子女指针很多,用于磁盘。基本操作代码如下:(仅供第二次复习的时候再来进行修改,还有不合适的地方,今天晚上头脑不清晰,第二次复习的时候再来看,补全代码以及相应习题)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值