二叉查找树总结附代码

二叉查找树(二叉搜索树,二叉排序树):

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树

(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;

(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;

(3)左、右子树也分别为二叉排序树;

(4)没有键值相等的节点。

其实总结下来简单来说就是,一个没有重复值的,左边比根小,右边比根大的二叉树

为了方便理解,我把二叉查找树的实现分为1,查;2,增;3,删;

查找:

bool SearchTree(BiTree T,int key,BiTree pre,BiTree &n){
	if(!T){   //如果树为空,返回false,且把n赋值给pre,方便后面的插入操作
		n=pre; 
		return false;
	}
	else if(key==T->data){
		n=T;   //找到了就把找到的给n;
		return true;
	}
	if(key<T-data)
		SearchTree(T->lchild,key,T,n);
	else 
		SearchTree(T->rchild,key,T,n);
}

n参数是代表他的父节点。不论是能否查找到,都会有一个返回他父亲节点的参数,方便后面的删除修改增加。

增加:

bool InsertBST(BiTree &T,int k){
	BiTNode* p;
	if(!SearchTree(T,k,NULL,p){            //二叉查找树不能有重复的键,只有找不到才能进行插入
 		BiTNode* temp=new BiTNode;
		temp->data=k;
		temp->lchild=temp->rchild=NULL;
		if(!p){    //只有树为空,p才会空,直接根节点等于temp.
			T=temp;
		}
		else{
			if(k>p->data){    //如果不为空,加入的k值就和p值相比较
				p->rchild=temp;
			}
			else
				p->lchild=temp;
		}
		return true;
	}
	else{
		return false;
	}
}

删除:

删除的话,总共有三种情况。

1,要删除的节点只有左子树;2,要删除的节点只有右子树;3,要删除的节点左右子树都有;

1,2种情况很简单,只需要把父亲节点接到它的子节点去。

第三种情况就要稍微复杂些,需要找到比这个要删除的节点大且距离这个节点最近的数(注意,所说的最近的意思是比这个数大却又大得有限的意思)。

所以先找到这个要删除的节点,然后找他的右子树,然后在右子树下无限找它的左子树。然后这个将这个左子树的值覆盖到要删除的节点上,然后将这个左子树free掉就完成了。

bool DeleElement(BiTree&T,int key)
 {
    
         if(!T)
          {
              return 0;   //树是空树的话就返回假
          }
         if(T->data==key)
         {
            BitNode*s,*p;
            if(T->rchild==NULL)   //只有右子树,情况2
            {   
                 s=T;
                 T=T->lchild;
                 free(s);
            }
            else if(T->lchild==NULL)
            {
                s=T;               //只有左子树,情况1
                T=T->rchild;
                free(s);
            }
            else
            {                      //情况3,左右子树都有
                p=T;
                s=T->rchild;
                while (s->lchild)
                {
                    p=s;           //找到所要删除节点的后继,那就是他的右孩子的左孩子
                    s=s->lchild;
                }
                T->data=s->data;    //用删除节点的后继替换所删除的节点
                if(p!=T)           
                {
                    p->lchild=NULL;   //所删除的节点的右孩子不是叶结点
                }
                else 
                    p->rchild=NULL;   //所删除的节点的右孩子是叶节点
                free(s);
            }
             return 1;
         }
         else if(key<T->data)
            DeleElement(T->lchild,key);    //去和他的左子树根去比较
         else 
            DeleElement(T->rchild,key);   //去和他的右子树根去比较

 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值