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

📄 p356.cpp

📁 经典的c++版数据结构教程
💻 CPP
字号:
#include "p353.cpp"
		template <class Type> int Btree<Type>::Remove ( const Type & x ) {
		//从驻留磁盘上的m阶B-树上删除x。
		   Triple<Type> loc = Search (x);			//在树中搜索x
		   if ( loc.tag ) return 0;					//x不在B-树中, 返主
		   Mnode<Type> *p = loc.r, *q, *s;			//p是关键码x所在结点
		   int j = loc.i;						//j是关键码在结点中的位置
		   if ( p->ptr[j] != NULL ) {				//若p非叶结点
			 s = p->ptr[j];  GetNode (s);  q = p;		//读取磁盘上的s结点
			 while ( s != NULL ) { q = s;  s = s->ptr[0]; }	//找大于x但最接近于x的最小关键码(q是叶结点)
			 p->key[j] = q->key[1];				//用最小关键码填补
			 compress ( q, 1 );					//在q结点中关键码与指针前移填补key[1], q->n减1
			 p = q;						//下一步处理q结点中的删除
   		   }
		   else compress ( p, j );					//p是叶结点, 关键码与指针前移填补key[j], p->n减1
		   int d = (m+1)/2;						//结点容纳关键码的下限
		   if (!(p==root))
		   while (1) {
			 if ( p->n < d-1 ) {					//需要调整
			   j = 0;  q = p->parent;			//在q中找指向p的指针
			   GetNode (q);
			   while ( j <= q->n && q->ptr[j] != p ) j++;
			   if ( !j ) LeftAdjust ( p, q, d, j );		//p是q的最左子女, 与其右兄弟与双亲结点做调整
			   else 
				if (j==q->n) RightAdjust ( p, q, d, j );			//p是q的最右子女, 与其左兄弟与双亲结点做调整
			   else													//p是中间,选择一个较简单的合并方法
				if ( (q->ptr[j+1]->n) > d-1 ) LeftAdjust(p,q,d,j);  
			   else
				RightAdjust ( p, q, d, j );		
			   p = q;						//继续向上做结点调整工作
			   if ( p == root ) break;
			 }
			 else break;						//不需要进行调整, 跳出循环
		   }
		   if ( !root->n ) {					//当根结点为空时删根结点
			 p = root->ptr[0];  delete root;  root = p;  
			 if (root) root->parent = NULL;
		   }
		   return 1;
		}

		template <class Type>
		void Btree<Type>::LeftAdjust ( Mnode<Type> *p, Mnode<Type> *q, const int d, const int j ) {
		   Mnode<Type> *p1 = q->ptr[j+1];			//p的右兄弟
		   if ( p1->n > d-1 ) {					//右兄弟空间还够, 不用合并, 仅做调整
			 ( p->n ) ++;
			 p->key[p->n] = q->key[j+1];			//双亲结点相应关键码下移
			 q->key[j+1] = p1->key[1];				//右兄弟最小关键码上移到双亲结点
			 p->ptr[p->n] = p1->ptr[0];			//右兄弟最左指针左移
			 compress ( p1, 0 );
		   }
		   else merge ( p, q, p1,j );				//p与p1合并, 保留p结点
		}
		template <class Type> void Btree<Type>::compress ( Mnode<Type> *p, const int j ) {
		   for ( int i=j; i<p->n; i++ )				//左移 
			 { p->key[i] = p->key[i+1];  p->ptr[i] = p->ptr[i+1]; }
		   p->n --;							//结点中元素个数减1
		}

		template <class Type>
		 void Btree<Type>::merge ( Mnode<Type> *p, Mnode<Type> *q, Mnode<Type> *p1, const int j) {
		   p->key[(p->n)+1] = q->key[j+1];			//从双亲结点下降一个关键码
		   p->ptr[(p->n)+1] = p1->ptr[0];			//从右兄弟结点左移一个指针
		   for ( int k=1; k<=p1->n; k++ ) {				//从右兄弟结点
		      p->key[(p->n)+k+1] = p1->key[k];		//关键码从p1到p左移
	      	p->ptr[(p->n)+k+1] = p1->ptr[k];		//指针从p1到p左移
		   }
		   compress ( q, j+1 );					//双亲结点q中值与指针左移
		   p->n = p->n + p1->n + 1;
		   delete p1;
		}

		template <class Type>
		void Btree<Type>::RightAdjust ( Mnode<Type> *p, Mnode<Type> *q, const int d, const int j )
		//此程序与LeftAdjust功能基本相同,但与LeftAdjust是对称的:左右指针互换,前端与后端互换。
		{
		   Mnode<Type> *p1 = q->ptr[j-1];			//p的左兄弟
		   if ( p1->n > d-1 ) {					//左兄弟空间还够, 不用合并, 仅做调整
			 ( p->n ) ++;
			 for (int i=p->n; i>=1;i--)
			 {
				 p->key[i]=p->key[i-1];
				 p->ptr[i]=p->ptr[i-1];
			 }
			 p->key[1]=q->key[j];
			 q->key[j]=p1->key[p1->n];
			 p->ptr[0]=p1->ptr[p1->n];
			 (p1->n)--;
		   }
		   else merge ( p1, q, p,j-1 );				//p1与p合并, 保留p结点
		}

⌨️ 快捷键说明

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