1. 程式人生 > >二叉排序樹關於刪除節點的方法(對上一部落格的補充)

二叉排序樹關於刪除節點的方法(對上一部落格的補充)

bool SortedBitree::DeleteBST(NodeBitree *&root,const int data){
	NodeBitree *index=NULL;
	if(NULL==root){
		std::cout<<"Empty Tree or not found"<<std::endl;
		return false;
	}else{
		if(root->getdata()==data){
			return Delete(root);
		}
		else if(data<root->getdata())
			return DeleteBST(root->getLchild(),data);
		else
			return DeleteBST(root->getRchild(),data);
	}
}
 bool Delete(NodeBitree *p){ 
  NodeBitree *q, *s;
   if (!p->getLchild() && !p->getRchild())
  {
      
  }
  else if(!p->getRchild()){	//右子樹空則只需重接它的左子樹
	  q=p->getLchild();
    p->setdata(p->getLchild()->getdata());
    p->getLchild()=p->getLchild()->getLchild();
    p->getRchild()=p->getLchild()->getRchild();
  }
  else if(!p->getLchild()){	//左子樹空只需重接它的右子樹
    q=p->getRchild();
    p->setdata(p->getRchild()->getdata());
    p->getLchild()=p->getRchild()->getLchild();
    p->getRchild()=p->getRchild()->getRchild();
 }  else{
		NodeBitree *s,*q;
		q=p;
		s=p->getLchild();
		while(s->getRchild()){
			q=s;
			s=s->getRchild();
		}
		p->setdata(s->getdata());
		if(q!=p){
			q->getRchild()=s->getLchild();
		}else{
			q->getLchild()=s->getLchild();
		}
	}
	return true;
  }

演算法導論第三版上關於刪除節點的演算法,指出了需要刪除節點和實際刪除節點

在紅黑樹時,將NULL變為NIL,並且去掉第一個函式末尾的判斷

下面的程式碼

TRANSPLANT(T,u,v){
	if(u.p==NULL)
		T.root=v;
	else if(u=u.p.left)
		u.p.left=v;
	else
		u.p.right=v;
	if(v!=NULL)//在紅黑樹中詞句略去
		v.p=u.p;
}

TREE_DEL(T,z){
	if(z.left==NULL)
		TRANSPLANT(T,z,z.right);
	else if(z.right==NULL)
		TRANSPLANT(T,z,z.left);
	else{
		y=TREE_MIN(z.right);
		if(y.p!=z){
			TRANSPLANT(T,y,y.right);
			y.right=z.right;
			y.right.p=y
		}
		TRANSPLANT(T,z,y);
		y.left=z.left;
		y.left.p=y;
}

上面的TRANSPLANT解決了元素替換是上層建築的結構問題,替換後,下層建築的結構還需自己動手連線。