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

📄 btree.cpp

📁 一个简单的b tree 实现代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

						   if(nm->d==0 &&nm->p[0]==NULL)
							t->p[i]==NULL;
							else
							{
							t1=MergeNode(nl,nm,0);
							 l1=i;
							}
							t->d--;
							}
					   }

					  i=i;

					}

                    if (le==btree_level&& t1!=NULL && root->d<1 ) {
					  root=t1;
					  btree_level--;
					 }

				  if(t->d>0)
				  if(t->p[ l1 ]->d==0 )// 叶子节点中已经为空
				  {  //将该叶子节点从索引中删除

					 if(i>0)
					 DelFromNode(t,l1-1);
					 else
					 DelFromNode(t,l1);
					 //t->d--;
				  }
				  // 比较索引对应的节点第一项是否有与索引对应
				  //有则修改
				  if (t->d>=0 && i<=t->d)
				   if((t->p[ i ]->min!=t->k[i-1] ) &&(i>=1)  )
					 {
					   t->k[i-1]= t->p[ i]->min ;
					   t->v[0]=NULL;
					 }
					 else if(i==0 && t->min!=t->p[0]->min)
					 {
					  t->min =t->p[0]->min ;
					 }
					//当 t->d 小于M时 考虑左移 或右移 到临近节点上,
					//并将父节点中的索引删除

			 }
			 else                     //判断为节点
			{
			if (key == t->k [ i ])
				{
				   if(t->v[ i ]!= NULL)
				   {
						//memset(t->v[i],0x0,20);       //删除节点
							#ifdef key_string
							t->k[ i ]=null_string;
							#else
							t->k[ i ]=0;
							#endif
						free(t->v[i]);
				   }
						DelFromNode(t,i);     //维护父节点索引


					btree_count--;


					t->d--;

					if (t->k[ 0 ]!=t->min)
					 t->min=t->k[ 0 ];
				 }
				 else{
				 printf("key not found\n");
				 }

				}

		


}

btree tree::RebuildIndexNode(btree t)
{
  node p,temp[2*M];
  btree p1,t2;
  p1=&p;
  t2=&temp[0];
  int i,j,k=0,l=0;

  memset(p1,0x0,sizeof(node));
  memset(t2,0x0,sizeof(node));

   memcpy(p1,t,sizeof(node));
  for(i=0;i<=t->d;i++)
  {

   for(j=0;j<t->p[i]->d;j++)
	{
	  t2->p[k]=t->p[i]->p[j];
	  t2->k[k]=t->p[i]->k[j];
	  t2->v[k]=t->p[i]->v[j];

	   t2->d++;
	  if( j==2*M-1)
		t2->p[k+1]=t->p[i]->p[j+1];

	  k++;
	  if(k>=2*M-1)
	  {
	   if(t2->p[0]==NULL)
		t2->min=t2->k[0];
		else
		 t2->min=t2->p[0]->min;
		   t2->p[k+1]=t->p[i]->p[j+1];
	  // memcpy(p1->p[l],t2,sizeof(node));
	   k=0;
	   l++;
	   t2=&temp[l];
	   memset(t2,0x0,sizeof(node));
	  }
	}

  }
  if(t2->d>0)
  { if(t2->p[0]==NULL)
		t2->min=t2->k[0];
		else
		 t2->min=t2->p[0]->min;
	   //memcpy(p1->p[l],&t2,sizeof(node));
	   k=0;
	  // l++;
	  // t2=&temp[l];
	  // memset(&t2,0x0,sizeof(node));
  }
	  for(i=0;i<l;i++)
		memcpy(p1->p[i],&temp[i],sizeof(node));
	 memcpy(t,p1,sizeof(node));
}

float tree::use_rate(btree t)
{
if(t->p[0]=NULL)
 return (t->d/(2*M));//叶子节点占用率

int x=0;
for(int i=0;i<=t->d;i++)
{
x+=t->p[i]->d;
}
return x/((t->d+1)*2*M);//索引节点占用率
}

btree tree::MergeLeafNodeBack(btree t1,btree t2,int d,int l)
{
int i,m,j;
m=d;
	for(i=0;i<d;i++)
	{
		   if(i<t2->d)
			{
				t2->k[i+m]=t2->k[i];
				t2->v[i+m]=t2->v[i];
				t2->p[i+m]=t2->p[i];
			}
			t2->k[i]=t1->k[t1->d-m+i];
			t2->v[i]=t1->v[t1->d-m+i];
			t2->p[i]=t1->p[t1->d-m+i];
            	#ifdef key_string
					t1->k[t1->d-m+i]=null_string;
				#else
				t1->k[t1->d-m+i]=0;
				#endif

			t1->v[t1->d-m+i]=NULL;
			t1->p[t1->d-m+i]=NULL;
	}
	t2->d+=m;
	t1->d-=m;
	return t2;

}

btree tree::MergeLeafNode(btree t1,btree t2,int d,int l)
{
int i,m,j;
  if (d==0)
  if (l>0)
  (2*M+1-t1->d)>t2->d?m=t2->d:m=2*M+1-t1->d;
 else
   (2*M-t1->d)>t2->d?m=t2->d:m=2*M-t1->d;
  else
  m=d;
  j=t1->d;
   for(i=0;i<m;i++)
	{
	 t1->k[j+i]=t2->k[i];
	 t1->v[j+i]=t2->v[i];
	 t1->p[j+i]=t2->p[i];

	}
	t1->d+=m;
	if (t2->d-m>0)
	  for(i=0;i<t2->d-m;i++)
		{
			t2->k[i]=t2->k[i+m];
			t2->v[i]=t2->v[i+m];
			t2->p[i]=t2->p[i+m];
		}


	t2->d-=m;



	if (t2->d>0) t2->min=t2->k[0];
	return  t1;
}

btree tree::MergeNode(btree t1,btree t2,int d)
{
 //将 t2 的数据 移动到t1  若移动后T2没有数据则释放 t2 的空间
 //移动时T1 的最小值要小于 T2
  if(t1->min>t2->min)
  return NULL;

   if(t1->d==0 && t1->p[0]==NULL) t1->min=t2->min;
  int i,j,m;
  if (d==0)
  (2*M-t1->d)>t2->d?m=t2->d:m=2*M-t1->d;
  else
  m=d;
  //判断是否为叶子节点
  if(t1->p[0]!=NULL && t1->d>0 && t2->d>0)
  {
	 j=t1->d+1;
	 for(i=0;i<m;i++)
	{
	 t1->k[j+i]=t2->k[i];
	 t1->v[j+i]=t2->v[i];
	 t1->p[j+i]=t2->p[i];
	 t2->k[i]=t2->k[i+m];
	 t2->v[i]=t2->v[i+m];
	 t2->p[i]=t2->p[i+m];
	}
	 t1->p[j+i]=t2->p[i];
	 t1->k[t1->d] =t2->min;
	 t1->d+=m+1;
	 t2->d-=m;
	//  if(t2->d<=0)
	//  free(t2);
  }
  else
  {
  j=t1->d;
  for(i=0;i<m;i++)
  {
	 t1->k[j+i]=t2->k[i];
	 t1->v[j+i]=t2->v[i];
	 t1->p[j+i+1]=t2->p[i+1];

	 t2->k[i]=t2->k[i+m];
	 t2->v[i]=t2->v[i+m];
	 t2->p[i]=t2->p[i+m];

  }
	 t1->p[j+i+1]=t2->p[i+1];

	 if (t2->d<=0 && t2->p[0]!=NULL) {
	 t1->p[t1->d+1]=t2->p[0];
	  t1->k[t1->d]=t2->min;
	  t1->d++;
	 } else
	 {
	 t1->d+=m;
	 t2->d-=m;
	  }
	 //if(t2->d<=0)
	 //free(t2);
   }
	return t1;

}

/*
* 把一个键和对应的右子树从一个节点中删除
*/
void tree::DelFromNode(btree t, int d)
{
	int i;
	/* 把所有大于要删除的键值的键左移 */
	if (i==2*M) {}
	for(i=d;i <= t->d-1; i++) {
		t->k[ i ] = t->k[i+1];
		t->v[ i ] = t->v[i+1];
		t->p[ i ] = t->p[i+1];
	}


}

btree tree::NewRoot(btree t,btree nt)
{
	btree temp;
	temp = (btree)malloc(sizeof(node));
	memset(temp,0x0,sizeof(node));
	temp->d = 2;
	temp->p[0] = t;
	temp->p[1] = nt;
	temp->k[0] = t->k[0];
	temp->k[1] = nt->k[0];
	temp->v[0] = NULL;
	temp->v[1] = NULL;
	btree_level++;

	/* if(btree_level>1)
			  {
				temp->k[0] =InsKey;
				temp->v[0] = InsValue;
				//temp->p[0]=NewTree;
	}

  /*	if (	nt->p[0]!=NULL)
	 { for(int i=0;i<nt->d;i++)
	  {
		nt->k[i]=nt->k[i+1];
		nt->v[i]=nt->v[i+1];
		nt->p[i]=nt->p[i+1];

	  }
		  nt->d--;
	  }
	*/


	node_sum++;
	return(temp);
}
/*
* 建立有两个子树和一个键的根节点
*/
btree tree::NewRoot(btree t)
{
	btree temp;
	temp = (btree)malloc(sizeof(node));
	memset(temp,0x0,sizeof(node));
	temp->d = 1;
    temp->p[0] = t; 
	temp->p[1] = NewTree;
	temp->k[0] = InsKey;
	temp->v[0] = InsValue;
	btree_level++;
	node_sum++;
	return(temp);
}
/*
* 释放根节点,并返回它的最左子树
*/
btree tree::FreeRoot(btree t)
{
	btree temp;
	temp = t->p[0];
	free(t);
   // btree_level--;
	node_sum--;
	return temp;
}

void tree::Error(int f,typekey key)
{
	if (f==1)
		printf("Btrees error: Insert %d!\n",key);
	else if(f==0)
		printf("Btrees error: delete %d!\n",key);

}

int tree::height(btree t)
{
	return btree_level;
}

int tree::count( )
{
	return btree_count;
}
double tree::payload(btree t)
{
	if (node_sum==0)
		return 1;
	return (double)btree_count/(node_sum*(2*M));
}
btree tree::deltree (btree t)
{
	level=btree_level;
	btree_level = 0;
	delall(t,level);

	root=(btree)malloc(sizeof(node));
	memset(root,0x0,sizeof(node));
	return root;

}

btree tree::delall(btree t,int l)
{


	int i,j,m;

	   for(i=0 ; i<t->d;i++)
	   {


		   if(l==0)
		  if( t->v[i]!=NULL )
			  free(t->v[i]  );
		  else
		   if(t->p[i]!=NULL )
			  delall(t->p[i],l-1);

	   }


	return NULL;
}

int tree::print(  )
{
	 print_tree(root,btree_level);
	return 0;

	}

int tree::print_tree(btree t, int n)
{
	 int i,j,m,l;
	  l=n;


		j=t->d;

		//printf("nc=%d ",t->d );
	   for(i=0 ; i<t->d;i++)
	   {

		  if (l<btree_level)
		  if ((i>0 &&l>0) ||(l==0) )
				{
					 for(m=0;m<btree_level-l;m++)
					   printf("     ");
					   printf("+");


					 for(m=0;m<btree_level-l;m++)
						printf("--");
				}

		   if(l==0)
			  {
			  #ifdef key_string
			  printf("l%d t->k[%d]=%s  v=%s  \n",l,i,t->k [i].c_str(),t->v[i]  );
			  #else
			  printf("l%d t->k[%d]=%d  v=%s  \n",l,i,t->k [i],t->v[i]  );
			  #endif
			  }
			else  if (i>0)
		  {
		   #ifdef key_string
				printf("l%d t->k[%d]=%s  v=%s min=%d\n",l,i-1,t->k [i].c_str(),t->v[i],t->min );
			  #else
		  printf("l%d t->k[%d]=%d  v=%s min=%d\n",l,i-1,t->k [i],t->v[i],t->min );
		  #endif
		  }


		   if(t->p[i]!=0 )
			  print_tree(t->p[i],l-1);




	   }

	 //  if( t->p[t->d]!=NULL )
	 //	 print_tree(t->p[t->d],l-1);


		return i;
	}


tree* menu_do(char c,  tree* t,long n )
{

	//printf("a=add, d=delete, e=empty, f=find, m=menu, p=print, q=quit\n");
	int k,i;
   tree  *t1=t;
	 btree  t_search ;
	switch (c) {
		case 'a':
			{
					char *x=(char*)malloc(20);

					sprintf(x,"%d",n);
					#ifdef key_string
					char b[20];
					sprintf(b,"%d",n);
					 string st;
					  st.assign(b);

					 t->insert(st,t->root,x);
					#else
					t->insert(n,t->root,x);
					#endif
			}
			break;
	   case 'g':
		{  	for(i=10;i<10*n;i+=10)
			{
			#ifdef key_string
					char b[20];
					sprintf(b,"%d",i);
					 string st;
					  st.assign(b);
			t->delete_n(st,t->root);
			#else
			t->delete_n(i,t->root);
			#endif
			}
		}
		break;

		case 'r':
		{
			t->RebuildIndexNode(t->root);
		}
		break;
		case 'x':
		{    char *x;
			for(i=1340000;i<1390000;i+=1)
			{	 x=(char *)malloc(20);
					sprintf(x,"%d",i);
				#ifdef key_string
					char b[20];
					sprintf(b,"%d",i);
					 string st;
					  st.assign(b);
				t->insert(st,t->root,x);
				#else

				t->insert(i,t->root,x);
				#endif
			}
		}
		break;
		case 'b':
		{    	int pos=-1;
			for(i=1340000;i<1390000;i+=1)
			{
				  pos=-1;
				  #ifdef key_string
						char b[20];
						sprintf(b,"%d",i);
						 string st;
						st.assign(b);
						 t_search=t->search(st,t->root,&pos);
					  #else
						t_search=t->search(i,t->root,&pos);
					#endif
			if(pos>=0)
		   {} //	printf("found key pos=%d,k=%d,k0=%d\n",pos,t_search->k[pos],t_search->k[0]);
			else
				printf(" key not found\n");
			}


		}
		break;
		case 't':
		{   char *x;

		  for(i=10;i<10*n;i+=10)
		   //	 for(i=10*n;i>0;i-=10)
			{
				x=(char *)malloc(10);
				if (x!=NULL) {


				sprintf(x,"%d",i);
			   if(i==641)
			   i=i;

				#ifdef key_string
						char b[20]={0};
						sprintf(b,"%d",i);
						 string st;
						st.assign(b);
				t->insert(st,t->root,x);
				#else
			   t->insert(i,t->root,x);
				#endif
			  // if(x!=NULL)
			  // free(x);

				}else{printf("malloc error");}

			}

			i=205;
					#ifdef key_string
			char b[20]={0};
			 char *x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
					sprintf(b,"9test1");
						 string st;
						st.assign(b);
				 t->insert(st,t->root,x1);

					 i=300;
				 x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
					sprintf(b,"8test2");
						// string st;
						st.assign(b);
				 t->insert(st,t->root,x1);

				 x1=(char*)malloc(20);
				sprintf(x1,"tttt" );
					sprintf(b,"7test2");
						// string st;
						st.assign(b);
				 t->insert(st,t->root,x1);

				#endif
			 /*	 char *x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
				 t->insert(i,t->root,x1);

					i=215;
				 x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
				 t->insert(i,t->root,x1);
					i=225;
				 x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
				 t->insert(i,t->root,x1);
					i=235;
				 x1=(char*)malloc(20);
				sprintf(x1,"%d",i);
				 t->insert(i,t->root,x1);

			   */
			 if (t1!=NULL)
			 printf("insert %d\n",n);
			 else
				printf("insert error\n");


			}
			break;
		case 'c':
		 printf("btree count=%d\n",t->count());
			break;
		case 'd':
		   {
		  #ifdef key_string
						char b[20];
						sprintf(b,"%d",i);
						 string st;
						st.assign(b);
				t->delete_n(st,t->root);
				#else
		  t->delete_n(n,t->root);
		  #endif
		   }
			break;
		case 'e':
		{    int pos=-1;
			 char b[20];
			 for(i=10;i<10*n;i+=10)
			 {      pos=-1;
					#ifdef key_string

						sprintf(b,"%d",i);
						 string st;
						st.assign(b);
						 t_search=t->search(st,t->root,&pos);
					 #else
					 t_search=t->search(i,t->root,&pos);
					 #endif
				 if(pos<0)
					printf(" key  %d not found \n",i);

			  }
			}
			break;
		case 'f':
			t->deltree(t->root);
		break;
	  case 's':
			{	int pos=-1;

				#ifdef key_string
						char b[20];
						sprintf(b,"%d",n);
						 string st;
						st.assign(b);
		 t_search=t->search(st,t->root,&pos);
				#else
		 t_search=t->search(n,t->root,&pos);
			 #endif
		if(pos>=0)
			printf("found key pos=%d,k=%d,k0=%d\n",pos,t_search->k[pos],t_search->k[0]);
			else
				printf(" key not found\n");
			}
					break;
		case 'p':
			//printf("level=%d\n",btree_level);

		   t->print( );
			break;
		case 'm':
			printf("a=add, d=delete, e=empty, f=find, m=menu, p=print, q=quit\n");
		default:
			printf("a=add, d=delete, e=empty, f=find, m=menu, p=print, q=quit\n");
			break;
	}

	return t1;
	}


void menu_response(char *c, long *n)
{
	char s[1024];

	printf(">");
	fflush(stdout);
	*n = 0;
	if (fgets(s, sizeof(s), stdin) == NULL)
		*c = 'q';
	else {
		
	 
		*c = *s;
		 
		 if (strlen(s) > 1)
		 *n = atol(s+1);
	}
}

int main(int argc, char ** argv)
{
		char c;
		long n;
		 tree *t;
		 t=new tree();
	//t=	NewRoot(t1);
	do {
		menu_response(&c, &n);
		if (c != 'q')
			menu_do(c, t,n);
	} while (c != 'q');
	   //	t->deltree(t->root);
		return 1;
	exit(0);
	}

⌨️ 快捷键说明

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