二叉排序树

一 概念

  二叉排序树或者是空树,或者是满足如下性质的二叉树:

  1.若它的左子树不空,则左子树上所有的关键字的值均小于根关键字的值。

  2.若它的右子树不空,则右子树上所有关键字的值均大于根关键字的值。

  3.左右子树又是一棵二叉排序树

二 BST的算法

   1.查找关键字的算法

    由BST的定义可知,根结点中的关键字将所有的关键字分成了两部分,即大于根节点中关键字的部分和小于根节点关键字的部分。可以将待查关键字先和根节点中关键字比较,如果相等则查找成功;如果相等则查找成功;如果小于则到左子树中去查找,如果大于则到右子树中查找。来到当前树的子树根中,重复上述过程。如果来到了结点的空指针与,则说明查找失败,实际上折半查找的判定树就是一个二叉排序树。

BTNode * BSTSearch(BTNode * bt,int key) 
{ 
    if(bt==NULL) 
        return NULL; 
    else  
    { 
        if(bt->weight==key) 
            return bt; 
        else if (key<bt->weight) 
            return BSTSearch(bt->lchild,key); 
        else 
            return BSTSearch(bt->rchild,key); 
    } 
}

2.插入关键字算法

   二叉排序树是一个查找表,插入一个关键字时首先要找到插入位置。对一个不存在于二叉排序数中的关键字,其查找不成功的位置即为该关键字的插入位置。因此只需对查找关键字的算法进行修改,在来到空指针的时候将关键字插入。

BTNode * Insert(BTNode * root,datatype w)
{
       if(root==NULL)
       {
         root=(BTNode *)malloc(sizeof(BTNode));
        
	         root->weight=w;
	         root->lchild=NULL;
	         root->rchild=NULL;
	       	 return root;
       
          
       }       
       else if ( root->weight==w )
       		return root;
       else if (root !=NULL && w>root->weight)
       	
	        {
		 root->rchild=Insert(root->rchild,w);
		 return root;
	        }
		else
		{
		root->lchild=Insert(root->lchild,w);
		return root;
		}
}
3.二叉排序树的构造

二叉排序树的构造就变得非常简单,只需要建立一棵空树,然后将关键字逐个插入到空树中即可。

4.二叉排序树的删除

二叉排序树的删除分为三种情况

假设要删除的结点为*q,其双亲结点为*f,可设*p是*f的左孩子,分三种情况进行讨论

1)若*p结点为叶子结点,直接删除即可

2)*p只有右子树而无左子树,或者只有左子树而无右子树。此时只需将p删掉,然后将p的子树直接连接在原来p与其双亲结点f相连的指针上即可。

3)*p结点既有左子树又有右子树。将*p的直接前驱代替*p,然后删除p的直接前驱。但是要注意,删除p的直接前驱时,不要忘记把p的之间前驱s的左子树接到s的父节点的右子树上。

int  del (BTNode * & p)//删除结点指针为p的结点

{
 	 BTNode *q,*s;
	 if(p==NULL)
	  			 return ERROR ;
	  else
	  {
	  	if(!p->lchild)//左子树为空只需要接右子树

			{
				q=p;p=p->rchild;free(q);
			}
		else if(!p->rchild)//右子树空
		{
			q=p;p=p->lchild;free(q);
		}
		else//左右为空,用中序遍历的p结点的前驱直接覆盖p的值,然后重接s的左右子树

		{
			q=p;s=p->lchild;
			while(s->rchild){q=s;s=s->rchild;}
			p->weight=s->weight;
			if(q!=p) q->rchild=s->lchild;
			else
				q->lchild=s->lchild;//说明p的左子树的右子树空

			
			free(s);
		}

		return OK;
	  
	  }	  
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值