⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mybplustree.cpp

📁 B+树的演示程序
💻 CPP
字号:
// MyBPlusTree.cpp : 实现文件
//

#include "stdafx.h"
#include "MyBPlusTree.h"
#include "MyControl.h"

// MyBPlusTree

MyBPlusTree::MyBPlusTree()
{	
	m_levels = 0;
	m_nodes = 0; 
	m_keys = 0;
	m_root = NULL;
	m_current = NULL;
	N = MINIMUS_NUMBER_OF_NODE;
	M = (N+1)/2;
}

MyBPlusTree::~MyBPlusTree()
{
	if(m_root)
		DeleteTree();
}

void MyBPlusTree::SetParent(void* pParent)
{
	m_pParent = pParent;
}
// MyBPlusTree 成员函数
bool MyBPlusTree::Create(int n/*=MINIMUS_NUMBER_OF_NODE*/)
{
	if( (n<MINIMUS_NUMBER_OF_NODE) || (n > MAXIMUM_NUMBER_OF_NODE) )
		return false;
	MyNode::SetMaxNumber(n);
	N = n;
	M = (N+1)/2;
	m_root = new MyLeaf();
	if(!m_root)
		return false;
	if(!m_root->Create())
		return false;
	m_current = m_root;
	m_levels++;
	m_nodes++;
	return true;
}
long* MyBPlusTree::Search(long key)				// if Null , there isn't this key
{
	int i;
	if( (!m_root) || (!m_current) )
		return NULL;
	i = SearchKey(m_root,key,1);

	if(m_current->k[i] == key)
		return (long*)m_current->p[i];
	else
		return NULL;
	// Draw search key: (MyNode*) m_current->m_itype = 1; node.i .
}
int MyBPlusTree::SearchKey(MyNode* node,long key,int level)
{
	int i;
	i = node->Search(key);
	m_current = node;
    if(node->m_level > level)
		i = SearchKey((MyNode*)node->p[i],key,level);
	return i;
}

int MyBPlusTree::Insert(long key,long* pkey)	// return number of new node , -1 already this key ,-2 memory error
{
	// Is there key in B+ tree ?
    if(Search(key))		return -1;

	int n = m_nodes;
	if(!InsertKey(key,(MyNode*)pkey,1))
        return -2;	// fail to split new node!
	m_keys++;
	return (m_nodes - n);
}
bool MyBPlusTree::InsertKey(long key,MyNode* pnode,int level)
{
	int i;
	if( (!m_root) || (!m_current) )
		return false;
	i = SearchKey(m_root,key,level);

	// Draw Insert key: m_itype; (MyNode*) m_current, (MyNode*)/(long*) pnode .
	((MyControl*)m_pParent)->m_bSleep = true;
	if(m_current->m_level == 1)
		((MyControl*)m_pParent)->Display(m_current->k[0],m_current->m_level,10,(void*)pnode);
	else
		((MyControl*)m_pParent)->Display(((MyNode*)m_current->p[i])->k[0],m_current->m_level-1,11,(void*)pnode);

	if(m_current->m_n < N)
	{
		m_current->Insert(key,pnode,i);
		return true;
	}
	else
		return SplitNode(m_current,key,pnode,level,i);
}

bool MyBPlusTree::SplitNode(MyNode* node,long key,MyNode* pnode,int level,int i)
{
	int m;
	MyNode* nnode = NULL;
	if(node->m_level == 1)
		nnode = new MyLeaf();
	else
		nnode = new MyBranch(node->m_level);
	if(!nnode) return false;
	if(!nnode->Create())	return false;
	m_nodes++;
	m = (i<M) ? 1 : 0;

	node->SplitNode(nnode,m);

    if(i < M)
		node->Insert(key,pnode,i);
	else
		nnode->Insert(key,pnode,i-M);

	// Draw Split Node: node->m_itype = 2; MyNode* node,MyNode* nnode .
	((MyControl*)m_pParent)->m_bSleep = true;
	((MyControl*)m_pParent)->Display(node->k[0],node->m_level,13,(void*)nnode);

	if(node->m_level == m_levels)
	{
		// 根结点时
		m_root = new MyBranch;
		if(!m_root)		return false;
		if(!m_root->CreateRoot(nnode->GetMinKey(),node,nnode))
			return false;		
		m_levels++;
		m_nodes++;
		
		// Draw New Root: m_root->m_itype = 1;
		((MyControl*)m_pParent)->m_bSleep = true;
		((MyControl*)m_pParent)->Display(nnode->k[0],nnode->m_level,12);
		return true;
	}
	else	
		return InsertKey(nnode->GetMinKey(),nnode,level+1);
}
int MyBPlusTree::Delete(long key)				// return number of del node , -1 none this key , -2 there is no key in B+key
{
	if(m_keys == 0)		return -2;
	if(!Search(key))	return -1;

	int n;
	n = m_nodes;
    DeleteKey(key,1);
	m_keys--;
	return (n - m_nodes);
}
void MyBPlusTree::DeleteKey(long key,int level)
{
	int i,m;
	i = SearchKey(m_root,key,level);
	//MyNode* tnode;

	// 删除至根结点时
	if(level == m_levels)
	{
		/*
		tnode = m_current;
		((MyControl*)m_pParent)->m_bSleep = true;
		((MyControl*)m_pParent)->Display(m_root->k[0],m_root->m_level,20,NULL,i);
		m_current = tnode;
		if( (m_root->m_n = 1) && (m_levels > 1) )
		{
			tnode = m_current;
			 ((MyControl*)m_pParent)->m_bSleep = true;
			 ((MyControl*)m_pParent)->Display(m_root->k[0],m_root->m_level,21);
			m_current = tnode;
		}*/
		m_root->Delete(i);
		if( (m_root->m_n < 1) && (m_levels > 1) )
		{
			MyNode* temp;
			temp = (MyNode*)m_root->p[0];
			m_root->Release();
			delete m_root;
			m_root = temp;
            m_levels--;
			m_nodes--;
			// Draw delete root: m_root;
		}
		return;
	}
	m = (level == 1) ? M : (M-1);
	// Draw delete key: m_current,i .

	/*
	tnode = m_current;
	((MyControl*)m_pParent)->m_bSleep = true;
	((MyControl*)m_pParent)->Display(m_current->k[0],m_current->m_level,20,NULL,i);
	m_current = tnode;
	*/

	if(m_current->m_n > m)
		m_current->Delete(i);	
	else
		JudgeNbrNode(m_current,key,level,i);
	return;
}

int MyBPlusTree::JudgeNbrNode(MyNode* node,long key,int level,int i)
{
	int j,m;
	long temp;
	MyNode* lnode = NULL;
	MyNode* rnode = NULL;
	j = SearchKey(m_root,key,level+1);
	//current node is the father node ,he has 2-3 children: lnode, node, rnode.
	m = (level == 1) ? 1 : 0;

	if(j > 0)
	{
		// 左相邻结点有可移动的键值
		lnode = (MyNode*)m_current->p[j-1];
		if(lnode->m_n > M-1+m)
		{
			node->Delete(i);
			temp = node->GetMinKey();

			// Draw get key from left: node
			node->GetKeyFromLeft(lnode);			

			Update(temp,level+1);
			return 1;
		}
	}
	if(j < m_current->m_n)
	{
		// 右相邻结点有可移动的键值
		rnode = (MyNode*)m_current->p[j+1];
		if(rnode->m_n > M-1+m)
		{
			node->Delete(i);

			// Draw get key from Right: node
			node->GetKeyFromRight(rnode);
			

			Update(rnode->GetMinKey(),level+1);
			return 2;
		}
	}

	// 左右都无可移动键值
	
	node->Delete(i);

	if(lnode)
	{
		// 有左相邻结点时,将该结点与左邻结点合并,将该结点向左移
		// Draw unite with left: lnode
		temp = lnode->UniteRight(node);
		if(node)
		{
			node->Release();
			delete node;
		}
	}
	else
	{
		// 有右相邻结点时,将该结点与右邻结点合并,将右结点移入该结点
		// Draw unite with right: node
		temp = node->UniteRight(rnode);
		if(rnode)
		{
			rnode->Release();
			delete rnode;
		}
	}
	
	m_nodes--;

	DeleteKey(temp,level+1);
	return -1; 
}
void MyBPlusTree::Update(long key,int level)
{
	int i;
	i = SearchKey(m_root,key,level);

	if(i == 0)	i++;
	m_current->k[i-1] = m_current->GetMinKey(i);

	if(level < m_levels)
		Update(key,level+1);
	return;
}

void MyBPlusTree::DeleteTree()
{
	if(m_keys == 0)
		return ;
	DelTree(m_root);
	m_root = NULL;
	m_current = NULL;
	m_levels = 0;
	m_nodes = 0;
	m_keys = 0;
}
void MyBPlusTree::DelTree(MyNode* node)
{
	if(m_levels == 1)
	{
		m_root->Release();
		delete m_root;
		m_root = NULL;
		return;
	}
	int i,j,m;	
	m = node->m_level;
	j = node->m_n;
	MyNode** pnode = new MyNode*[N+1];

	if(m > 1)
		for(i=0;i<j+1;i++)
			pnode[i] = (MyNode*)node->p[i];
	if(node)
	{		
		node->Release();
        delete node;
	}

	if(m > 1)
		for(i=0;i<j+1;i++)
			DelTree(pnode[i]);
	delete [] pnode;
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -