ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二叉排序树树的查找、插入、删除

2021-11-16 12:32:53  阅读:155  来源: 互联网

标签:树树 结点 return 二叉 else 查找 key 排序


文章目录


参考博文:《二叉排序树的查找、插入、删除》

一、定义

二叉排序树(BST)(二叉查找树)或者是一棵空树,或者是具有下列特性的二叉树:

1)若左子树非空,则左子树上所有的结点的值均小于根结点的值。

2)若右子树非空,则右子树上所有结点的值均大于根结点的值。

3)左右子树均是一棵二叉排序树

注意:由二叉排序树的定义可知,左子树结点值<根结点值<右子树结点值,所以如果我们对二叉排序树进行中序遍历(左根右),可以得到一个递增(这里的递增是针对于结点值而言,也就是查找的关键字)的有序序列

二叉树排序树的结构体

/*其实就是二叉树的二叉链表的结点定义*/
typedef struct BiTNode
{
    ElemType data;//关键字
    struct BiTNode *lchild,*rchild;//左右孩子
}BiTNode,*BiTree;

二叉排序树的建立

void CreatBST(BiTree &T,KeyType str[],int n)
{
    T=NULL;
    int i=0;
    while(i<n)
    {
        InsertBST(T,str[i]);
        i++;
    }
}

二、二叉排序树的查找

算法描述:从根结点开始,沿着某个分支逐层向下比较。若二叉排序树非空,先将给定值与根结点的关键字比较,若相等,则查找成功;若不等,如果小于根结点的关键字,则在根结点的左子树上查找,否则在根结点的右子树上查找。

1.递归实现

int SearchBST(BiTree T,int key,BiTree f,BiTree &p)//二叉树f指向T的双亲
{
    if(T==NULL)
    {
        p=f;
        return 0;
    }
    else if(key==T->data)//查找成功,则P指向该数据元素结点
    {
        p=T;
        return 1;
    }
    else if(key<T->data)//在左子树中继续查找
    {
        return SearchBST(T->lchild,key,T,p);
    }
    else//在右子树中继续查找
    {
        return SearchBST(T->rchild,key,T,p);
    }
}

2.非递归实现

BiTNode *SearchBST(BiTree T,ElemType key)
{
    while(T!=NULL&&key!=T->data)//若树为空或者等于根结点值,则结束循环
    {
        if(key<T->data)//小于,则在左子树查找
        {
            T=T->lchild;
        }
        else//大于,则在右子树查找
        {
            T=T->rchild;
        }
    }
    return T;
}

三、二叉排序树的插入

算法描述:若二叉排序树为空,则直接插入结点;否则,若关键字key小于根节点值,则插入到左子树,若关键字key大于根结点值,则插入到右子树。

注意:插入的结点一定是一个新添加的叶子结点,且是查找失败时的查找路径上访问的最后一个结点的左孩子或右孩子。

int insertBST(BiTree &T,KeyType key)
{
    if(T==NULL)
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=key;
        T->lchild=T->rchild=NULL;
        return 1;
    }
    else if(key==T->data)
    {
        return 0;
    }
    else if(key<T->data)
    {
        return InsertBST(T->lchild,key);
    }
    else
    {
        return InsertBST(T->rchild,key);
    }
}

四、二叉排序树的删除

算法描述:分三种情况

  • 若被删除结点是叶子结点,则直接删除,不会破坏二叉排序树的性质。
  • 若被删除结点只有左子树或者右子树,则让该结点的子树代替该结点的位置。
  • 若被删除结点有左右两棵子树,则令该结点中序遍历下的直接前驱或直接后继替代该结点,然后从二叉排序树中删去这个直接前驱或直接后继,这样就转换成了第一或第二种情况。

在这里插入图片描述

/* 从二叉排序树中删除结点p,并重接它的左或右子树。 */
int Delete(BiTree &p)
{
	BiTree q,s;
	if(p->rchild==NULL) /* 右子树空则只需重接它的左子树(待删结点是叶子也走此分支) */
	{
		q=p;p=p->lchild; free(q);
	}
	else if(p->lchild==NULL) /* 只需重接它的右子树 */
	{
		q=p; p=p->rchild; free(q);
	}
	else /* 左右子树均不空 */
	{
		q=p; s=p->lchild;
		while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
		{
			q=s;
			s=s->rchild;
		}
		p->data=s->data; /*  s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值) */
		if(q!=p)
        {
            q->rchild=s->lchild; /*  重接q的右子树 */
        }	 
		else//说明p==q,也就是说前面的while循环没有进行,也就是说一开始s没有右子树,此时直接将s的左子树接到q的左子树上就行
        {
            q->lchild=s->lchild; /*  重接q的左子树 */
        }	
		free(s);
	}
	return 1;
}

/* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点, */
/* 并返回1;否则返回0。 */
int DeleteBST(BiTree T,KeyType key)
{ 
	if(T==NULL) /* 不存在关键字等于key的数据元素 */ 
    {
      	return 0;  
    }
	else
	{
		if (key==T->data) /* 找到关键字等于key的数据元素 */ 
        {
            return Delete(T);
        }	
		else if (key<T->data)
        {
            return DeleteBST(T->lchild,key);//左子树
        }	
		else
        {
            return DeleteBST(T->rchild,key);//右子树
        }	
	}
}

标签:树树,结点,return,二叉,else,查找,key,排序
来源: https://blog.csdn.net/weixin_51273111/article/details/121353156

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有